性能问答>full gc之后为啥老年代的空间变大了?>
5回复
2年前

full gc之后为啥老年代的空间变大了?



image.png

-Xms200m -XX:+UseSerialGC -XX:NewRatio=1 -XX:+PrintGC -XX:PretenureSizeThreshold=900000000000

以上是我的代码和配置,堆总共200m,老年代100m 新生代100m,默认8:1:1,收集器全用Serial,并且调高了直接进入老年代的阈值。

一次数组创建进去60m

image.png

这是第二个数组创建前的ygc,被form和to都太小直接就进了老年代。

image.png

这是第三个数组创建前的gc,因为我没将第一个数组的引用断开,本来以为会爆溢出,但是发现total直接变大了,两个数组都塞到了老年代。

既然来了就一起问了:

第一次ygc后新生代遗留的761k的是什么?
eden+from+to为什么不等于total?
为啥gc之后老年代扩容进一倍?

3899 阅读
请先登录,再评论

第一个问题,因为JVM启动的时候本身就会创建一些对象,在main函数执行之前就会创建,包括一些class对象本身也是heap里分配的,这个你可以在main方法第一行sleep,然后heap dump传到我们的在线内存分析产品上就能看到,https://memory.console.heapdump.cn/

第二个问题,因为打印的total只包括eden+from,并不是把to加上去,因为to正常情况都是空的,算进去意义不大

第三个问题,fgc扩容是因为会对old重新计算size,重新计算size的过程和一些参数和算法有关系,比如MinHeapFreeRatio等

我后面会在我们社区专门开一门JVM参数的课,欢迎参与讨论

12年前
回复 你假笨:

自带板凳,听课

2年前回复

坐等大佬开课

2年前

笨大大说的基本很完整了,我就说最后一点吧。你这里jvm参数设定了最小堆xms,并没有设定xmx,因此可能触发堆的扩容

2年前

-xmx也设置个值,就会报内存溢出了,不再扩容

2年前