JVM-垃圾回收算法与垃圾回收器

判断对象是否存活

1.引用计数法
给对象一个引用计数器,当对象加一个引用时计数器加1,引用失效减1,引用为0的对象可被回收。
优点:快,方便,实现简单
缺点:对象相互引用时(A.instance=B同时B.instance=A)很难判断是否该回收
2.可达性分析(Java中使用)
“GC Roots”向下搜索,走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何链接,则证明此对象不可用。
GC Roots对象包括以下几种:

  1. 当前虚拟机栈中局部变量表中引用的对象
  2. 当前本地方法栈中局部变量表中引用的对象
  3. 方法区中静态属性引用的对象
  4. 方法区中的常量引用的对象

引用

强引用:一般Object obj = new Object(),就属于强引用。
软引用(SoftReference):内存充足时不会回收,内存不足时回收
弱引用(WeakReference):垃圾回收器在扫描到该对象时,无论内存是否充足,都会回收。
虚引用(PhantomReference):最弱的引用,和没有引用一样

GC----Garbage collection

Minor GC: Eden区空间不足触发
Full GC:老年代空间不足触发, 同时也会执行了了Minor GC

垃圾回收算法

复制算法(Copying):
JVM-垃圾回收算法与垃圾回收器
优点:简单高效,不会出现内存碎片问题
缺点:1.内存利用率低,只有一半 2.存活对象较多时效率明显会降低

新生代Eden、form、to 8:1:1
Java中大多数对象是朝生夕死。只有10%的对象不会被回收10%(from) + 10%(to)(预留)

标记-清除算法(Mark-Sweep)
JVM-垃圾回收算法与垃圾回收器
优点:利用率100%
缺点:1.标记和清除的效率都不高(比复制算法) 2.产生大量不连续的内存碎片

标记整理(Mark-Compact):
JVM-垃圾回收算法与垃圾回收器
优点:利用率100%,没有内存碎片
缺点:标记和清除的效率都不高,效率相比标记-清除要低

垃圾回收器

分代收集:分新生代和老年代,单线程与多线程
所有新生代都是用复制算法,老年代标记整理和标记清除
CMS:使用标记清除
G1:使用标记整理和化整为零

并行:垃圾回收的多线程的同时进行
并发:拉垃圾回收器的多线程和应用的多线程同时进行

Serial/Serial Old:单线程,独占式,成熟,适合单CPU
-XX:+UseSerialGC 新生代老年代都用串行收集器
-XX:+UsePaNewGC 新生代用ParNew,老年代使用Serial Old
-XX:+UseParallelGC 新生代用ParallerGC,老年代使用Serial Old

ParNew:多线程,多CPU的,停顿时间比Serial少
-XX:+UseParNewGC 新生代ParNew,老年代使用Serial Old

ParallelScavenge(ParallerGC)/Parallel Old:关注吞吐量的垃圾收集器,适用运算任务,不需要太多交互。

Concurrent Mark Sweep(CMS) :以获取最短时间停顿的收集器,适用于B/S架构项目,关注用户响应时间。
-XX:+UseConCMarkSweepGC 一般新生代ParNew,老年代使用CMS

CMS使用标记-清除算法:
初始标记 仅仅标记GC Roots直接关联的对象,速度快,需要停顿(STW - Stop the world)
并发标记 从GC Roots开始对堆进行可达性分析,找存活对象,耗时长,不需要停顿
重新标记 标记并发标记时因用户线程继续操作,导致变动,需要标记,需要停顿,比初始标记时间稍长,比并发标记时间短
并发清除 不需要停顿

优点:服务暂时、响应时间快,性能高
缺点:1.并发暂用CPU高,2.有浮动垃圾(回收过程中产生的垃圾,找一个空间存放),3.内存碎片

G1垃圾收集器
-XX:+UseG1GC 使用G1垃圾收集器
算法:标记-整理和复制回收算法

Jdk1.9以后推荐使用G1:跨域了新生代和老年代
特点:1.空间整合,不会出现内存碎片问题2.可预测的停顿(总共1000个区域 一个区域10m*筛选常用的100个区域 急需回收)

G1 GC模式:1.Young GC(回收Eden、Survivor区) 2. Mixed GC(全部区域回收)

全局并发标记
1.初始标记:仅仅只是标记一下GC Roots能直接关联的对象,并且修改TAMS(Next Top Mark Start),的值,让下一阶段用户程序并发运行时,能够正确可以的Region中穿件对象,需要停顿(STW),耗时很短
2.并发标记 : 从GC Roots开始对堆进行可达性分析,找到或对象,此阶段耗时较长,但可以与用户程序并发执行
3.最终标记 : 修正正在并发标记期间用户继续操作导致的标记变动,这阶段需要停顿线程(STW),但是可并行执行
4.筛选回收 : 首先对各个Region中回收价值和成本进行排序,根据用户所期望的GC停顿时间来制定回收计划。与用户程序并发执行,因为只回收一部分Region,时间用户可控,停顿用户线程将大幅度提高收集效率。