JVM复盘- 垃圾回收CMS/G1

2021-12-26  本文已影响0人  莫妮卡笔记
image.png

一、CMS

image.png

我们常规熟悉的垃圾收集器逻辑分三个区域分别 新生代(包含三个区域 Eden/S0/S1区域)、老年代(old)、永久代(P区域)。

而在于JDK7之前我们一直使用的是CMS垃圾收集器、JDK8及以上都使用G1垃圾收集器。那他们本质上有什么区别?

我觉得最核心的还是ROI的问题,就是如何把收益最大化、我们都知道垃圾收集器有Top the world 问题,就是垃圾收集期间有停顿问题,不管CMS、G1都有这样的问题,但是CMS停顿是不可精准预测,也就是你不知道他会停顿多久。本质上就是说在CMS GC期间,他需要把用户线程都停下来;对内存对象进行标记清理。

在我们系统使用CMS一般优化就是内存不够用就调大一些、在极端业务场景的情况下;可能会根据业务场景来设置堆大小,比如调小可能GC的频率高;但是RT降低了;调大虽然GC频率低了、但每次触发RT 也提高了。

但一般业务场景是可以接受GC造成的停顿耗时;所以会在宿主机内存可用的情况下还是去调大内存,如果调小的话;对象回收不了也很容易造成内存溢出、风险更大。

二、G1

G1 逻辑上区域还是一样的。新生代(包含三个区域 Eden/S0/S1区域)、老年代(old) 但是他的结构发生了巨大的变化;就是说他把内存分为2048个内存块;每个块的大小在[1M,32M]之间。


image.png

分成块的目的是可以控制扫描范围、这是G1核心功能;你可以设置y每次GC的最大毫秒数、G1根据你设置的毫秒数来决定每次去回收多少个region 块。

很多细节懒得写,可以看看以下连接。

参考:
https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/G1GettingStarted/index.html
https://plumbr.io/handbook/garbage-collection-algorithms-implementations#serial-gc
https://zhuanlan.zhihu.com/p/52841787
https://github.com/sunwu51/notebook/blob/master/19.09/java_jvm%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86%E5%99%A8.md

上一篇下一篇

猜你喜欢

热点阅读