java垃圾回收机制

大纲:

  1. 虚拟机内存模型
  2. 判断对象已死
  3. 四种引用
  4. 垃圾回收算法
  5. 垃圾回收策略
  6. 垃圾回收器

 

一、虚拟机内存模型

根据 JVM 规范,JVM 运行时区域大致分为 方法区、堆、虚拟机栈、本地方法栈、程序计数器 五个部分。

 

二、判断对象已死

  1. 引用计数算法:为每个对象增加一个计数器,被引用一次+1,引用失效-1,引用数==0则回收。优点:简单,高效。缺点:如果2个对象除了相互引用外无其他引用,则无法回收。
  2. 可达性分析算法:一个对象通过一条引用链能达到gc roots则判定对象有效,否则会被回收。gc roots包括虚拟机栈中引用对象、方法区中类静态属性引用对象、方法区中常量引用的对象、native方法引用的对象。

 

三、四种引用

  1. StrongReference-强引用:Object o = new Object();gc不回收,内存满则抛出OutOfMemoryError。
  2. SoftReference-软引用:gc会在内存不足时回收,可以和ReferenceQueue联合使用,软引用引用对象被回收,虚拟机会把这个软引加到相关引用队列中。
  3. WeakReference-弱引用:gc只要发现弱引用的对象就回收,可以和ReferenceQueue联合使用,弱引用引用对象被回收,虚拟机会把这个弱引加到相关引用队列中。
  4. PhantomReference-虚引用 被虚引用引用的对象就和没有引用一样,虚引用必须和ReferenceQueue联合使用,gc回收前,发现对象被虚引用引用,就在回收前把虚引用加到相关队列中。

 

四、垃圾回收算法

  1. 标记清除-将垃圾标记后清除,但会造成内存碎片化
  2. 标记整理-将存活对象移动到一端,清除其他内存,解决了内存碎片化问题,但由于频繁移动内存导致效率低。
  3. 复制-将内存一分为二,每次使用一半,清理时将存活对象复制到另外一半,然后清理当前一半,但每次只能使用一半内存。
  4. 分代垃圾回收-虚拟机将堆分为老年代和年轻代,年轻代朝生夕死适合复制算法,老年代存活率高,适合标记清除、标记整理算法。

 

五、垃圾回收策略

 堆内存是虚拟机中主要管理区域,占用内存最大。

Java 堆主要分为2个区域-年轻代与老年代,其中年轻代又分 Eden 区和 Survivor 区,其中 Survivor 区又分 From 和 To 2个区。

Eden-由于98%的对象是朝生夕死,eden在年轻代占据大一些,大多数对象出生在eden区。每次eden满触发minor gc。

Survivor-from,to两块作用相同,当发生minor gc,eden和(from/to)中存活的对象被复制到(to/from)中。

Old-老年代占据着2/3的堆内存空间,major gc和full gc 的时候才会进行清理。老年代中包括:

  1. 大对象:避免在Survivor中来回复制,避免Survivor装不下。
  2. 长期存活对象:对象每次经历minor gc年龄+1,16岁后进入老年代。
  3. 动态对象年龄判定:虚拟机并不是永远地要求对象的年龄必须达到了MaxTenuringThreshold才能晋升老年代,如果在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无须等到MaxTenuringThreshold中要求的年龄。对应虚拟机参数-XX:TargetSurvivorRatio 目标存活率,默认为50%

 

六、垃圾回收器

下图为垃圾回收器的常见组合,垃圾回收器分新生代回收器,老年代回收器,全年代回收器(G1)

1.Serial:单线程,每次回收STW

2.ParNew:Serial多线程版本

3.Parallel Scavenge:ps是一个吞吐量优先的收集器,在后台任务比较多的应用上使用。可以控制吞吐量(工作时间/工作时间+gc时间),默认使用GC自适应策略(动态调整新生代各部分大小),主要参数:

  • XX:MaxGCPauseMillis 控制最大的垃圾收集停顿时间
  • XX:GCRatio 直接设置吞吐量的大小
  • 参与回收的线程数量

4.Serial Old:Serial老年代版本

5.Parallel Old:ps老年代版本

6.cms:停顿时间短,注重服务端响应速度,在直接与用户交互的互联网应用上使用,保证用户体验。

  cms垃圾回收有4个阶段,采用三色标记的方法进行标记(黑色:本身及子结点全部被垃圾回收器访问过;灰色:本身被访问,子结点未被全部访问;白色:未被访问过)

    1.初始标记:stw,对象初始为白色,gcroots为黑色,将gcroots直接引用的对象标记灰色

    2.并发标记:根据可达性分析,在用户线程不停止的情况下,扫描灰色及其子结点;同时并发标记期间黑色结点新增的引用关系会被记录下来,因为会出现引用消失问题(某个白色结点本来被灰色结点引用,突然这个引用消失,但被黑色结点重新引用,由于黑色            结点不被再次扫描,所以在并发标记后该对象还是白色)

    3.重新标记:stw,扫描并发标记阶段黑色结点新增的引用关系,解决对象消失问题,避免误删除

    4.并发清除:并发清除白色标记的对象

  cms缺点:

    1.并发标记和并发清除占用cpu

    2.由于并发,无法清除浮动垃圾,当浮动垃圾产生的速度大于并发清除速度,老年代的空间被占用到一定比例时,需要Serial Old来帮忙进行依次major gc

    3.采用标记清除算法,产生内存碎片,碎片严重时,需要Serial Old来帮忙进行依次major gc

7.g1:全年代的垃圾回收器,延迟可控的情况下,尽量提高应用吞吐量

  g1特点:

    1.将堆内存默认分为2048个等大的Region,每个Region可以是年轻代,也可以是老年代,还有可能时大对象,每代不再时一个连续的区域。每个Region有自己的回收价值(垃圾对象比例,预期回收时间与效果)

    2.可以设置停顿时间,控制每次垃圾回收的总时长

    3.回收时,筛选价值高的Region来回收,由于有停顿时间限制,可分多次回收

    4.靠新生代、老年代达到Region的比例来判断是否需要进行回收

    5.标记过程与cms一样采用三色标记

 

posted @ 2021-06-19 17:37  扶不起的刘阿斗  阅读(111)  评论(0编辑  收藏  举报