Open yuanrengu opened 4 years ago
ZGC作为一种比较新的收集器,目前还没有得到大范围的关注,大家只需当科普看看即可,暂不需深究。
对于分配率高且稳定,而且大部分对象寿命很短的应用程序,我们可以通过如下方式进行调优:
将新生代设置得较大
以这种方式配置Eden和Survivor空间,可以尽可能使真正的短寿命对象不被晋升。
CMS 是英文 Concurrent Mark-Sweep 的简称,是以牺牲吞吐量为代价来获得最短回收停顿时间
的垃圾回收器。对于要求服务器响应速度的应用上,这种垃圾回收器非常适合。在启动 JVM 的参数加上“-XX:+UseConcMarkSweepGC”来指定使用 CMS 垃圾回收器。
CMS 使用的是标记-清除
的算法实现的,所以在 gc 的时候回产生大量的内存碎片,当剩余内存不能满足程序运行要求时,系统将会出现 Concurrent Mode Failure,临时 CMS 会采用 Serial Old 回收器进行垃圾清除,此时的性能将会被降低。
分代回收器有两个分区:老年代和新生代,新生代默认的空间占比总空间的 1/3,老年代的默认占比是 2/3。
新生代使用的是复制算法,新生代里有 3 个分区:Eden、To Survivor、From Survivor,它们的默认占比是 8:1:1,它的执行流程如下:
每次在 From Survivor 到 To Survivor 移动时都存活的对象,年龄就 +1,当年龄到达 15(默认配置是 15)时,升级为老年代。大对象也会直接进入老年代。
很棒,学到啦
着色指针
和读屏障
技术,解决了转移过程中准确访问对象的问题,实现了并发转移。GC Roots集合大小
,停顿时间不会随着堆的大小或者活跃对象的大小而增加。根据实际情况来看,获取内存快照可能会让系统暂停或阻塞一段时间,根据内存量决定。
使用jmap时,如果指定live
参数,则会触发一次FullGC,需要注意。
可以扩展阅读美团的新一代垃圾回收器ZGC的探索与实践
GC 频率
:高频的 FullGC 会给系统带来非常大的性能消耗,虽然 MinorGC 相对 FullGC 来说好了许多,但过多的 MinorGC 仍会给系统带来压力。内存
:这里的内存指的是堆内存
大小,堆内存又分为年轻代内存和老年代内存。首先我们要分析堆内存大小是否合适,其实是分析年轻代和老年代的比例是否合适。如果内存不足或分配不均匀,会增加 FullGC,严重的将导致 CPU 持续爆满,影响系统性能。吞吐量
:频繁的 FullGC 将会引起线程的上下文切换,增加系统的性能开销,从而影响每次处理的线程请求,最终导致系统的吞吐量下降。延时
:JVM 的 GC 持续时间也会影响到每次请求的响应时间。调整堆内存空间减少 FullGC
调整年轻代减少 MinorGC
:通过调整堆内存大小,我们已经提升了整体的吞吐量,降低了响应时间。那还有优化空间吗?我们还可以将年轻代设置得大一些,从而减少一些 MinorGC设置 Eden、Survivor 区比例
:在 JVM 中,如果开启 AdaptiveSizePolicy,则每次 GC 后都会重新计算 Eden、From Survivor 和 To Survivor 区的大小,计算依据是 GC 过程中统计的 GC 时间、吞吐量、内存占用量。这个时候 SurvivorRatio 默认设置的比例会失效。
https://yuanrengu.github.io/2020/4c889127.html
在开始介绍CMS和G1前,我们可以剧透几点: 根据不同分代的特点,收集器可能不同。有些收集器可以同时用于新生代和老年代,而有些时候,则需要分别为新生代或老年代选用合适的收集器。一般来说,新生代收集器的收集频率较高,应选用性能高效的收集器;而老年代收集器收集次数相对较少,对空间较为敏感,应当避免选择基于复制算法的收集器。 在垃圾收集执行的时刻,应用程序需要暂停运行。 可以串行收集,也可以并行收集。