垃圾回收浅析
#### golang 垃圾回收浅析
Base on go 1.13
GC
首先需要想清楚的问题是,什么是GC?
GC是一种自动内存管理方式。支持GC的语言无需手动管理内存, 程序后台自动判断对象是否存活并回收其内存空间, 使开发人员从内存管理上解脱出来。
现如今很多语言都支持GC,比如Java,go,Python等,不过GC的原理和基本算法都没有太大的改变。
这里有一些核心的概念:
并发和并行:通常在GC领域中, 并发收集器则指垃圾回收的同时应用程序也在执行; 并行收集器指垃圾回收采取多个线程利用多个CPU一起进行GC. 不过一般我们说并发回收器, 就包含了这两层意思.
Safepoint: 安全点(Safepoint)是收集器能够识别出线程执行栈上的所有引用的一点或一段时间。
Stop The World(STW): 某些垃圾回收算法或者某个阶段进行时需要将应用程序完全暂停.
Mark: 从Root对象开始扫描, 标记出其引用的对象, 及这些对象引用的对象, 如此循环, 标记所有可达的对象.
Sweep: Sweep清除阶段扫描堆区域, 回收在标记阶段标记为Dead的对象, 通常通过空闲链表(free list)的方式.需要的 工作量和堆大小成正比.
评价GC的性能,我们有一些关心的指标:
- 程序吞吐量: 回收算法会在多大程度上拖慢程序? 可以通过GC占用的CPU与其他CPU时间的百分比描述
- GC吞吐量: 在给定的CPU时间内, 回收器可以回收多少垃圾?
- 堆内存开销: 回收器最少需要多少额外的内存开销?
- 停顿时间: 回收器会造成多大的停顿?
- 停顿频率: 回收器造成的停顿频率是怎样的?
- 停顿分布: 停顿有时候很长, 有时候很短? 还是选择长一点但保持一致的停顿时间?
- 分配性能: 新内存的分配是快, 慢还是无法预测?
- 压缩: 当堆内存里还有小块碎片化的内存可用时, 回收器是否仍然抛出内存不足(OOM)的错误?如果不是, 那么你是否 发现程序越来越慢, 并最终死掉, 尽管仍然还有足够的内存可用?
- 并发:回收器是如何利用多核机器的?
- 伸缩:当堆内存变大时, 回收器该如何工作?
- 调优:回收器的默认使用或在进行调优时, 它的配置有多复杂? 预热时间:回收算法是否会根据已发生的行为进行自我调节?如果是, 需要多长时间? 页释放:回收算法会把未使用的内存释放回给操作系统吗?如果会, 会在什么时候发生?