21

CMS GC 新生代默认是多大?

 5 years ago
source link: https://www.tuicool.com/articles/mEnUFnJ
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

点击上方" 涤生的博客 ",关注我

转载请注明原创出处,谢谢

如果读完觉得有收获的话,欢迎加关注

问题

首先抛个问题给大家,看下面 JVM 参数配置:

猜一猜按照这样的 JVM 参数配置,YoungGen(新生代)是多大呢? 你一定会觉得这还不简单吗,NewRatio 默认为 2,也就是 YoungGen 与 OldGen(老年代)的比例是 1:2,那 YoungGen 大小应该是 2048M/3 = 672M。 真的是这样吗?jmap -heap pid 看看 iIBnuiz.jpg!web

然而结果居然是 332.75M(说明下案例中的 JDK 版本是 7)。

分析

要想知道原因,只能撸源码了。 我们从 Arguments(是用来解析 JVM 参数)类的 set cms and parnew gc_flags 函数说起,看函数名也知道是对 CMS 和 ParNew GC 的参数设置。 aIFjYva.jpg!web

看提示 1,在 MaxNewSize 和 NewRatio 都是默认配置时,MaxNewSize 值为 preferred max new size,而 preferred max new size 是什么呢? 看提示 2,align size up 主要是字节对齐用的,可以不用关系细节,所以 preferred max new size 主要取决于 preferred max new size unaligned, 再看提示 3,preferred max new size_unaligned 的值为

,也就是取 max heap/(NewRatio+1) 和 ScaleForWordSize(young gen per worker * parallel gc threads) 中较小的那个,max_heap/(NewRatio+1) 这个我们都了解,就是按照 NewRatio 来计算,ScaleForWordSize 又是什么呢?我们来看下 ScaleForWordSize 的定义: RnqimmR.jpg!web

因为这里我们是 64 位的机器,所以看上面的那行,align size down_ 这个也是字节对齐的,所以 ScaleForWordSize 返回值约为 (x) * 13 / 10,也就是 young gen per worker * parallel gc threads * 13 / 10 。因此,我们再看看 young gen per worker 和 parallel gc threads 的取值,而 young gen per worker = CMSYoungGenPerWorker, CMSYoungGenPerWorker 在另一块代码中有定义,跟硬件相关,x86 机器为 64M;而 parallel gc threads 的值呢? parallel gc_threads = (ParallelGCThreads == 0 ? 1 : ParallelGCThreads),所以我们得看 ParallelGCThreads 的设置 77byia2.jpg!web

可知,ParallelGCThreads 在没有设置的情况下会设置成 parallel worker threads 函数返回值,我们接着看 parallel worker threads 函数: 2aMr2ai.jpg!web

再看 calc parallel worker_threads 函数: R3Qrie7.jpg!web

在看 nof parallel worker_threads 函数: NJVBRfB.jpg!web

根据上面三个函数,ParallelGCThreads 最终由 nof parallel worker_threads 函数计算出,其中 ncpus 是 cpu 的核数,测试机器是 4 核,所以 ncpus 为 4,按照上面的公式计算,因此, ParallelGCThreads 为 4。

所以绕了半天,ScaleForWordSize 的值大约是 64M * 4 * 13 / 10 = 332.8M,再做下对齐就得到 332.75M 了;max_heap / (NewRatio+1) 的值为2048M / 3 = 672M,而新生代的值取了较小的 ScaleForWordSize,故为 332.75M。

总结

看到上面的过程,是不是有点奔溃。YoungGen 的大小在没有设置的情况下是通过计算得出的,其大小可能与 NewRatio 的默认配置没什么关系而与ParallelGCThreads 的配置有一定的关系。 那么既然 YoungGen 大小有不确定性,我们最好还是通过这些 -XX:NewSize、-XX:MaxNewSize 或者 -xmn 参数设置下,免得遇到一些奇怪的 GC,让你措手不及。

喜欢本文的朋友们,欢迎长按下图关注订阅号 涤生的博客 ,收看更多精彩内容

aMveiqB.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK