1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > 年轻代gc耗时真的比老年代短?

年轻代gc耗时真的比老年代短?

时间:2022-08-16 04:17:31

相关推荐

年轻代gc耗时真的比老年代短?

调整JVM参数如下:

-XX:NewSize=104857600—新生代大小为100m-XX:MaxNewSize=104857600—新生代最大大小为100m-Xms200M—初始堆大小为200m-Xmx200M—最大堆大小为200m-XX:+UseParNewGC:新生代使用ParNewGC垃圾回收器-XX:+UseConcMarkSweepGC---老年代使用CMS-XX:+PrintGCDetails---打印GC详细日志-XX:+PrintGCTimeStamps—打印GC时间-XX:SurvivorRatio=8—设置eden区和survivor区的比例为8:1:1-XX:PretenureSizeThreshold=209715200—设置最大对象的阈值为20m

测试demo

package com.example.springboot.jvm;import java.util.concurrent.TimeUnit;public class 年轻代gc耗时真的比老年代短 {public static void loadData() throws InterruptedException {byte[] data = null;for (int i = 0; i < 4; i++) {//每个请求10mdata = new byte[10 * 1024 * 1024];}data = null;byte[] data1 = new byte[10 * 1024 * 1024];byte[] data2 = new byte[10 * 1024 * 1024];byte[] data3 = new byte[10 * 1024 * 1024];data3 = new byte[10 * 1024 * 1024];//睡眠1秒TimeUnit.SECONDS.sleep(1);}public static void main(String[] args) throws InterruptedException {//这里睡眠20秒是为了能够有足够的时间打命令,看到的效果可以更直观TimeUnit.SECONDS.sleep(20);while (true) {loadData();}}}

启动服务,进入命令行界面。

先输入命令jps,查看各个进程,结果如下:

从结果中可以得到启动程序对应的进程号为3222。

输入命令jstat -gc 3222 1000 1000,表示统计进程3222的JVM运行状态,然后每隔一秒钟打印统计信息,持续打印1000次,结果如下:

可以发现EU列(Eden区)每次大概增加10M左右的对象,OU列(老年代)每次大概新增20~30M左右的对象,同时每秒触发一次新生代GC,老年代大致每3秒一次GC,不过此时的YGCT(年轻代GC总耗时)远远大于FGCT(老年代GC总耗时),即使双方各除以他们的总次数YGC(年轻代GC总次数)或者FGC(老年代GC总次数),年轻代GC的平均耗时也远远大于老年代GC的耗时。

这里先解释下为什么Eden区每次大概增加10M左右的对象,老年代每次大概新增20~30M左右的对象?

首先堆的大小设置为200,新生代的大小被设置为100M,同时Eden区和两个Survivor区的比例是8:1:1,那么Eden区的大小就是80M,两个Survivor区各为10M,老年代的大小为100M。

回顾代码,每秒会新建40M左右的对象,然后立马置空,让这40M对象失去引用变成垃圾对象,接着继续新建了data1,data2,data3三个对象,每个对象大小各为10M,这时候Eden区就被占用了大致70M左右的空间,最后又将data3变量引用指向另一个10M对象,此时Eden区空间已经不够分配这10M对象了,所以会触发新生代GC,此时40M垃圾对象会被回收,但是data1,data2,data3这三个变量的引用还是有效的,所以GC后一共有30M左右的对象存活,而Survivor区只有10M大小,是放不下30M对象的,因此这30M对象会直接被分配到老年代,然后再分配data3变量最后引用的10M对象,所以每秒Eden区会被占用10M空间。

为什么此时的年轻代gc耗时比老年代长?

一般来说,在固有的印象里,年轻代gc耗时比老年代要短得多,真正影响系统性能的应该是老年代GC产生的STW时间,但是在该示例中,年轻代的gc耗时比老年代要长,这是因为,老年代每次会新增20~30M左右的对象,新生代GC后的存活对象有30M左右,老年代空间放不下时,就会触发Full GC,腾出空间后,等到存活对象进入老年代了,新生代GC才算结束。因此可以理解成,本次的新生代GC时间其实是叠加了老年代GC时间的,所以新生代gc耗时才会比老年代长。

总结

如果每次年轻代GC时,都会触发老年代GC,那么年轻代GC耗时就会比老年代长了。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。