垃圾回收(GC)
垃圾的定义:运行程序中没有任何指针指向的对象
垃圾回收相关算法
- 垃圾标记阶段算法(对象存活判断,对象死亡定义:不再被任何存活对象继续引用时,就宣布死亡)
算法名称 | 算法详情 | 优点 | 缺点 |
---|---|---|---|
引用计数算法(Reference Counting) | java并没有采用该算法,对每一个对象保存一个整数的引用计数器属性,用于记录对象被引用的情况 | 实现简单,垃圾对象便于标识,判断效率高,回收没有延迟性 | 存储计数器,增加内存开销,每次赋值都需增减,增加了时间开销,无法处理循环引用的情况 |
可达性分析算法(Tracing Garbage Collection 根搜索算法,追踪性垃圾收集) | 以根对象集合(GC Roots)为起点,按照从上至下的方式搜索跟对象集合所连接的目标对象是否可达,搜索所走过的路径为引用链(Reference Chain),如果没有任何应用链相连,则是不可达,可标记为垃圾对象 | 实现简单,垃圾对象便于标识,判断效率高,解决了循环引用 |
- 垃圾清除阶段算法
算法名称 | 算法详情 | 优点 | 缺点 |
---|---|---|---|
标记-清除算法(Mark-Sweep) | 堆中可用内存不足,停止整个程序(stop the world),然后标记从引用根节点开始遍历,收集器标记所有引用的对象,在header中记录为可达对象,收集器对堆内存从头到尾进行线性遍历,发现对象Header中没有标记为可达对象的,将其回收 | 基础常见 | 效率不高,发生stw,内存不连续,且维护空闲列表 |
复制算法(Copying) | 将活着的内存空间分为两块,每次只使用其中的一块,在垃圾回收时将正在使用的内存中的对象(活着的对象)复制到未使用的内存块中,之后清除正在使用的内存块中的所有对象(活着的对象+垃圾对象),交换两个内存的角色,最后完成垃圾回收 | 没有清除标记步奏更高效,复制对象保证空间连续性 | 需要更大的内存空间,空间浪费,G1垃圾回收器指针引用关系内存占用以及时间开销大 |
标记-压缩算法(Mark-Compact) | 第一阶段和标记清除算法一样,从根节点开始标记所有被引用对象,第二阶段将所有存活对象压缩到内存的一端,按顺序排放,之后清除边界外所有的空间 | 消除标记-清除算法中内存碎片的问题,消除了复制算法的内存double开销 | 效率低于复制算法,移动对象被其他引用,则还需要调整引用,stw事件 |
分代收集算法(Generational Collecting) | 结合分代在各个代上使用上述三种算法 | ||
增量收集算法(Incremental Collecting) | 垃圾收集线程和引用线程交替执行,每次只收集一小片区域的内存空间,接着切换到应用线程交替执行,以此反复,直到垃圾全部收集完成 | 任然是以标记-清除和复制算法为基础,清除stw事件 | 线程切换和上下文切换的消耗,系统吞吐量下降 |
分区算法(Incremental Collecting) | 堆空间划分为多个小块,根绝目标的停顿事件,合理的回收若干个小区间,从而减少gc的停顿 |
垃圾回收器
垃圾回收器分类
分类 | 详情 |
---|---|
按线程分 | 串行垃圾回收器(Serial(新生代),Serial Old(老年代)),并行垃圾回收器(ParNew(新生代),Parallel Scavenge(新生代),Parallel Old(老年代)) |
按工作模式分 | 并发式垃圾回收器(CMS(老年代),G1(整堆收集器)),独占式垃圾回收器(stw) |
按碎片处理方式分 | 压缩式垃圾回收器,非压缩式垃圾回收器 |
按工作的内存区间分 | 年轻代垃圾回收器,老年代垃圾回收器 |
经典回收器详情
垃圾器 | 详情 | 优势 |
---|---|---|
Serial | 最基本历史最悠久的垃圾回收器,jdk1.3之前回收新生代的唯一选择,作为HotSpot中client模式下的默认新生代垃圾收集器,采用了复制算法,串行回收和stw机制的方式执行内存回收 | 单线程下简单而高效 |
Serial Old | 老年代垃圾回收,同样采用串行回收和stw机制,回收内存算法用的是标记-压缩算法,client模式下的默认老年代垃圾收集器,server模式下,可与新生代的Parallel Scavenge配合使用,也可作为CMS收集器的后备垃圾收集方案 | 单线程下简单而高效 |
ParNew | 与Serial几乎没有差别,同样采用了复制算法,并行回收和stw机制的方式执行内存回收 ,除了Serial,目前只有ParNew能与CMS收集器配合工作 | 多cpu下比Serial高效 |
Parallel Scavenge | 与ParNew几乎没有差别,同样采用了复制算法,并行回收和stw机制的方式执行内存回收 ,可控制的吞吐量(吞吐量优先),自适应调节策略 | 多cpu下比Serial高效 |
Parallel Old | 替代Serial Old收集器,采用了标记-压缩算法,并行回收和stw机制的方式执行内存回收 | 多cpu下比Serial高效 |
CMS(Concurrent-Mark-Sweep) | 采用了标记-清除算法,真正意义的并行回收和stw机制的方式执行内存回收 | 垃圾回收线程与用户线程同时工作,停顿时间短,响应速度块,低延迟 |
G1(Garbage First) | 作为jdk9 的默认垃圾回收器,取代CMS以及Parallel +Parallel Old的组合,G1将内存划分未一个个的region,内存回收以region为基本单位,region之间采用的是复制算法,整体上可看作标记压缩算法,避免内存碎片化 | 并行并发,分代收集,空间整合,可预测停顿模型,G1的内存占用以及执行负载都比CMS高,在小内存应用上CMS的表现大概率由于G1,G1在大内存应用上具有优势,平衡点在6-8G之间 |