你不得不知道的JVM 垃圾回收

一、四种引用方式
1.1 强引用
1.2 软引用(SoftReference)
1.3 弱引用(WeakReference)
1.4 虚引用(PhantomReference)

二、如何判断对象是垃圾
2.1 引用计数法
2.2 根可达性分析

三、垃圾回收算法
3.1 标记-清除(mark-sweep)
3.2 标记-整理(mark-compact)
3.3 标记-复制(mark-copy)

四、垃圾收集器
4.1 分类及特点简述
4.1.1 串行
4.1.2 吞吐量优先
4.1.3 响应时间优先
4.2 串行垃圾回收器详述
4.2.1 Serial
4.2.2 Serial-Old
4.2.3 流程图
4.3 吞吐量优先垃圾回收器详述
4.3.1 JVM相关参数
4.3.2 流程图
4.4、响应时间优先垃圾回收器详述
4.4.1 JVM相关参数
4.4.2 流程图
4.3.3 CMS的特点

五、G1垃圾回收器
5.1 相关JVM参数
5.2 特点
5.3 G1新生代垃圾回收
5.4 G1老年代垃圾回收

一、四种引用方式

1.1 强引用

只有所有 GC Roots对象都不通过【强引用】引用该对象,该对象才可以被回收。

1.2 软引用(SoftReference)

1.3 弱引用(WeakReference)

1.4 虚引用(PhantomReference)

二、如何判断对象是垃圾

2.1 引用计数法

某个对象只要有一处引用关系,该对象的引用次数就加1,如果一个对象的引用次数为0,则说明该对象是垃圾。

优势:实现简单,效率较高

弊端:如果有一对对象之间形成了相互引用,但是这两个对象都已经没有被其它对象所引用了,正常情况下,这一对对象应该被作为垃圾回收掉,但是因为形成了相互引用导致无法被回收。

2.2 根可达性分析

通过GC Root对象开始向下寻找,寻找不到的对象即说明没有被引用,那么这些没有被引用的对象被认定为垃圾。

目前,如下对象可以作为GC Root对象:

你不得不知道的JVM 垃圾回收

三、垃圾回收算法

根据前面的描述,知道了哪些对象是垃圾需要被回收,那么回收是按照什么样的算法呢?

3.1 标记-清除(mark-sweep)

很好理解,即在GC的放生时候,先对所有对象进行根可达性分析,借此标记所有的垃圾对象;所有对象标记完毕之后会进行清理操作。

因此,总体来说,就是先标记再清除。

弊端;标记清除之后会产生大量不连续的内存碎片,碎片太多可能会导致程序运行过程中需要分配较大对象时,无法满足分配要求导致GC操作。

3.2 标记-整理(mark-compact)

该回收算法操作过程基本等同于标记-清除算法只不过,第二步有点区别,该种方式会在清除的过程中进行整理操作,这是最大的不同。

优势:最终不会出现若干空间碎片而导致的空间浪费。

弊端:在整理过程中带来的计算不可小觑。

3.3 标记-复制(mark-copy)

该种方式与前两种有较大的区别:

该种方式会将存储区分成两个部分,分别为From、To,其中From区域中可能存在着对象,而To区域始终为空,用做下一次接受数据做准备。

分别有两个指针指向这两个区域:From-Pointer、To-Pointer,

优点:这种算法非常适合早生夕死的对象

缺点:始终有一块内存区域是未使用的,造成空间的浪费。

四、垃圾收集器

垃圾收集器,就是实现了上述三种垃圾回收算法的具体实现

在Java中不同的“代”所保存的对象特点都不一样,因此Java在垃圾回收的选择上并没有偏爱一种,只采用一种算法方式,而是根据不同“代”对象的特点,采取不同的垃圾回收器(垃圾回收算法)。

4.1 分类及特点简述

4.1 串行

特点:

4.2 吞吐量优先

特点:

4.3 响应时间优先

特点:

4.2 串行垃圾回收器详述

JVM开关:-XX:+UseSerialGC = Serial + SerialOld

4.2.1 Serial

4.2.2 Serial-Old

4.2.3 流程图

你不得不知道的JVM 垃圾回收

4.3 吞吐量优先垃圾回收器详述

JDK1.8默认开启的,使用的算法本身与Serial是一致的,只是处理线程不一样而已。

4.3.1 JVM相关参数

4.3.2 流程图

你不得不知道的JVM 垃圾回收

4.4、响应时间优先垃圾回收器详述

4.4.1 JVM相关参数

4.4.2 流程图

你不得不知道的JVM 垃圾回收

上图是:CMS垃圾回收器在老年代GC的工作流程图:

  1. 初始标记:标记根对象 会引发STW 根对象较少,因此标记很快
  2. 并发标记:从根对象出发去标记剩余对象 不会引发STW 此处的标记可以与用户线程并发执行
  3. 重新标记:从第二步中得到的垃圾对象进行重新扫描 会引入STW 为了避免在并发标记的过程中,因为用户线程的继续执行导致部分垃圾对象又重新被引用
  4. 并发清理:对第三步最后得到的垃圾对象进行使用标记清除算法 不会引入STW 此处可以与用户线程并发执行

4.3.3 CMS的特点

  1. 在某些阶段垃圾清理线程可以与用户线程并发执行
  2. 最大限度减少STW时间
  3. 在并发标记的过程中,由垃圾对象重新变成有用对象则需要在重新标记中进行最后一步的筛选,但是有一种情况,无法处理,即:
  4. 在并发标记的过程中,用户线程新产生的浮动垃圾,则无法被识别,需要等到下一次垃圾回收才能清除掉
  5. 在整个清理的过程中,只有初始标记与重新标记需要进行STW,其余步骤都可以与用户线程并发的执行
  6. CMS老年代垃圾回收器有可能会退化到SerialOld老年代垃圾回收器:
  7. 因为某个对象无法存入内存时,且经过了新生代垃圾回收之后,仍然无法存入,此时需要进行老年代的垃圾回收,在老年代垃圾回收之后仍然无法存入,则此时认为并发失败,会退回到SerialOld进行一次老年代垃圾回收,若清理之后仍然无法存入,则会报错老年代OOM。

五、G1垃圾回收器

5.1 相关JVM参数

5.1 特点

5.2 G1新生代垃圾回收

经过上面的文字分析,新生代的Region个数为所有Region个数的5%;这个数值其实是很小的,那么当新生代Region不够用的时候,JVM会划分更多的Region个数给新生代;

当新生代的Region个数占比所有Region个数超过 60%时,就会进行一次新生代的垃圾回收。

新生代垃圾回收会造成STW。

具体的垃圾回收算法同其它几个新生代垃圾回收器一样,新生代都使用复制算法。

  1. 先进行STW,将所有的用户线程到一个安全点
  2. 将Eden的对象进行分析,将存活对象拷0贝到To、然后清空Eden,然后将原本的To Region,改成From Region。
  3. 当某个对象生命周期达到一个阈值的时候会晋升到老年代。

5.3 G1老年代垃圾回收

老年代垃圾回收触发机制与参数-XX:InitaingHeapOccupancyPercent有关。

但是需要注意的是:这一次的老年代回收,其实是一次混合垃圾回收,会同时清理新生代、老年代、Humongous。

与新生代回收算法一致,依然使用复制算法,但是垃圾回收的过程等同于老年代响应时间优先的CMS方式

流程分为:

  1. 初始标记,会发生STW
  2. 并发标记
  3. 最终标记,会发生STW
  4. 根据不同Region的回收价值,选用回收性价比最高的Region进行并发清理,而不像CMS不进行有选择性的进行回收,这就是为了控制STW的时间。
展开阅读全文

页面更新:2024-05-07

标签:可达性   垃圾   流程图   新生代   线程   算法   标记   对象   年代   时间

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top