JVM——垃圾回收(二)

垃圾回收器

1.1 串行类垃圾回收器(Serial)

特点:
1.单线程
2.堆内存较小,适合个人电脑

使用方法:-XX:+UseSerialGC = Serial + SerialOld

Serial:是指在新生代进行垃圾回收,采用的是复制算法;
SerialOld:是在老年代进行垃圾回收,采用的标记-整理算法;
在这里插入图片描述
当串行垃圾回收器发生时,所有的线程都要到达安全点位置,避免线程中的对象地址发生改变,程序紊乱。然后由于是单线程进行垃圾回收,其他的线程不能运行,所以发生堵塞,等到垃圾回收后,才能开始运行。

1.2吞吐量优先类垃圾回收器(Parall 并行)

特点
1.多线程
2.堆内存较大,多核 cpu
3.让单位时间内,STW (stop the world)的时间最短
比如在一个小时内发生了两次GC,每次的时间是0.2s,总共是0.4s。垃圾回收时间占比最低,这样就称吞吐量高。

使用方法
-XX:+UseParallelGC ~ -XX:+UseParallelOldGC
ParallelGC:(并行垃圾回收器)是指在新生代进行垃圾回收,采用的是复制算法;
ParallelOldGC:是在老年代进行垃圾回收,采用的标记-整理算法;

在通过以下方法来设置一些参数:
-XX:GCTimeRatio=ratio:期望的 GC 时间占总时间的比例,用来控制吞吐量。一般是20%。

-XX:MaxGCPauseMillis=ms:期望收集时间上限,用来控制垃圾回收对应用程序停顿的影响。一般是200ms。

-XX:ParallelGCThreads=n:控制ParallelGC工作是的线程数。

-XX:UseAdaptiveSizePolicy:自动调整新生代里面的各个区的大小比例。

但要注意停顿时间与吞吐量这两个目标是相悖的,降低停顿时间的同时也会引起吞吐量的降低。因此需要将目标控制在一个合适的范围内。
在这里插入图片描述

1.3响应时间优先类垃圾回收器(CMS)

特点
1.多线程
2.堆内存较大,多核 cpu
3.尽可能让单次 STW (stop the world)的时间最短
比如说在一个小时内发生了5次GC,每次的时间是0.1s,总时间是0.5s 。这就是响应时间优先。

使用方法:

-XX:+UseConcMarkSweepGC ~ -XX:+UseParNewGC ~ SerialOld
CMS垃圾回收器只会发生在老年代中。在新生代中用ParNewGC,也就是一个并行的垃圾回收器。而后面的SerialOldGC是在并发失败(下面会讲到什么导致并发失败)后用到的。

在这里插入图片描述
CMS 垃圾回收器,采用“标记-清除”算法,它的运作过程分为 4 个步骤:

1.初始标记
2.并发标记
3.重新标记
4.并发清除

其中,由图像就能看出来初始标记、重新标记这两个步骤仍然需要 Stop-the-world。

  1. 初始标记仅仅只是标记一下GC Roots(根对象),速度很快。

  2. 并发标记阶段就是找到根对象引用的对象。

  3. 重新标记阶段则是为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始阶段稍长一些,但远比并发标记的时间短。

  4. 并发清除是指只有一个线程在进行垃圾回收,其他的线程继续工作,但是这就导致在我并发清除的时候其他线程会产生一些垃圾,而无法清理,就出现了一些浮动垃圾。而当我们的浮动垃圾过多时,导致我们的内存不足而引发并发失败,此时CMS垃圾回收器就无法进行下去了,就采用我们之前讲到的SerialOld垃圾回收器。一旦发生并发失败,垃圾回收的时间就会增加很多。

CMS 垃圾回收器的优点:并发收集,低停顿。

1.5 G1 垃圾回收器

适用场景:
1.同时注重吞吐量(Throughput)和低延迟(Low latency),默认的暂停目标是 200 ms。
2.会将堆划分为多个大小相等的 Region。
整体上是 标记+整理 算法,两个区域之间是 复制 算法。这两种算法都意味着 G1 运作期间不会产生内存空间碎片,收集后能提供规整的可用内存。

相关 JVM 参数:
-XX:+UseG1GC
-XX:G1HeapRegionSize=size
-XX:MaxGCPauseMillis=time

G1的收集模式可分为三种:
在这里插入图片描述
Young GC:在分配一般对象(非巨型对象)时,当所有 Eden 区域使用达到最大阀值并且无法申请足够内存时,会触发一次 YoungGC。每次 Young GC 会回收所有 Eden 以及 Survivor 区,并且将存活对象复制到 Old 区以及另一部分的 Survivor 区。会 STW。
**YoungGC+并发标记:**在 Young GC 时会进行 GC Root 的初始标记
老年代占用堆空间比例达到阈值时,进行并发标记(不会 STW)。
Mixed GC:当越来越多的对象晋升到老年代时,为了避免堆内存被耗尽,虚拟机会触发一个混合的垃圾收集器,即 Mixed GC,该算法并不是一个 Old GC,除了回收整个新生代,还会回收一部分的老年代,这里需要注意:是一部分老年代,而不是全部老年代,可以选择哪些 Old 区域进行收集,从而可以对垃圾回收的耗时时间进行控制。G1 没有 Full GC概念。最终标记会 STW,拷贝存活也会 STW。

整个G1的流程大致为初始标记,并发标记,最终标记,复制清除。

卡表:在我们新生代收集的过程中可能遇到老年代引用新生代的问题,如果我们一个一个的去遍历老年代,未免造成的时间太长了,在这就引入了卡表的概念。

在这里插入图片描述
图中右侧的就是我们的卡表,如果老年代中引用了新生代的对象那么就认为这张卡是脏的。

在进行 Young GC 的时候,我们便可以不用扫描整个老年代,而是在卡表中寻找脏卡,并将脏卡中的对象加入到 Young GC 的GC Roots里。当完成所有脏卡的扫描之后,Java 虚拟机便会将所有脏卡的标识位清零。卡表能用于减少老年代的全堆空间扫描,这能很大的提升 GC 效率。

巨型对象:当一个对象大于 region 的一半时,称之为巨型对象。
特点:
1.G1 不会对巨型对象进行拷贝
2.回收时被优先考虑
3.G1 会跟踪老年代所有 incoming 引用,这样老年代 incoming 引用为0 的巨型对象就可以在新生代垃圾回收时处理掉

相关 VM 参数
堆初始大小 :-Xms
堆最大大小: -Xmx 或 -XX:MaxHeapSize=size
新生代大小 :-Xmn 或 (-XX:NewSize=size + -XX:MaxNewSize=size )
幸存区比例(动态) -XX:InitialSurvivorRatio=ratio 和 -XX:+UseAdaptiveSizePolicy
幸存区比例 :-XX:SurvivorRatio=ratio
晋升阈值 :-XX:MaxTenuringThreshold=threshold
晋升详情: -XX:+PrintTenuringDistribution
GC详情 :-XX:+PrintGCDetails -verbose:gc
FullGC 前 MinorGC :-XX:+ScavengeBeforeFullGC

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

真真最可爱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值