糖尿病康复,内容丰富有趣,生活中的好帮手!
糖尿病康复 > 054 JVM实战总结: 案例实战:每日百亿数据量的实时分析引擎 如何定位和解决频繁Ful

054 JVM实战总结: 案例实战:每日百亿数据量的实时分析引擎 如何定位和解决频繁Ful

时间:2021-01-06 07:36:09

相关推荐

054 JVM实战总结: 案例实战:每日百亿数据量的实时分析引擎 如何定位和解决频繁Ful

之前有位同学面试时的一个面试题:如何配置能让JVM不进行FullGC?大家仔细看完这篇文章应该就有答案了

1-7、回顾内容参照40讲 点击链接

8JVM参数与程序

参数配置:-XX:NewSize=100M-XX:MaxNewSize=100M-XX:InitialHeapSize=200M-XX:MaxHeapSize=200M-XX:SurvivorRatio=8-XX:MaxTenuringThreshold=15-XX:PretenureSizeThreshold=20M-XX:+UseParNewGC-XX:+UseConcMarkSweepGC-XX:+PrintGCDetails-XX:+PrintGCTimeStamps-Xloggc:d:/gc.log程序:public class _54_RealTimeEngine {static final int M = 1024 * 1024;static final int K = 1024;public static void main(String[] args) throws InterruptedException {Thread.sleep(20_000);while(true){loadData();}}private static void loadData() throws InterruptedException {byte[] data = null;for(int i=0;i<4;i++){data = new byte[10*M];}data = null;byte[] data1 = new byte[10*M];byte[] data2 = new byte[10*M];//触发第一次OLDGCbyte[] data3 = new byte[10*M];data3 = new byte[10*M];//触发第一次YGCThread.sleep(1_000);}private static void allocate(int size) {byte[] bytes = new byte[size];}}

程序说明:

每秒有80M的对象要分配到堆中,其中30M在1秒内是存活的。

事实上垃圾收集时的存活对象要看是在哪条语句触发了GC,比如在byte[] data1 = new byte[10*M];语句触发GC ,那么存活对象是0

10、基于jstat分析程序运行的状态

??问题

1、红色1标注的区域,为什么每次都增加10M,而不是每次存活的30M?

答:执行到data3 = new byte[10*M];时发现Eden不够放,触发YoungGC,30M存活复制到S区,发现放不下,直接放入老年代,YGC后Eden放入10M。

2、红色2、3标注的区域,为什么第一次OU增加了30M ,后面增加的是10M或20M?

答:比如第二次YGC时OU增加了20M,是因为Eden区本身已经有10M,这时是执行到byte[] data3 = new byte[10*M];触发YGC,也就是说提前了一条语句触发,此时存活20M,这20M晋升,然后放入byte[] data3 = new byte[10*M]; data3 = new byte[10*M];生成的对象

3、红色3标注的区域,为什么到了60多M就会变成30M,而不是OU回收完的0M?

答:此时Eden区已存在30M多点,Eden区不够放,触发了YGC,结果发现老年代也不够放,触发OldGC,回收完是0M,然后放入存活30M

4、红色4标注的区域,为什么YGC从7直接变成了9?

答:eden放不下(触发了YGC -1),且S区放不下,直接放老年代(此时没有对Eden区回收),发现老年代也放不下了,触发OldGC,,回收完是0M,然后放入存活30M。再然后放入触发YGC的10M,发现Eden放不下,再次触发了YGC -2

5、红色5标注的区域,为什么会连续3秒FullGC

答:触发FullGC原因就是老年代空间不够放晋升对象了。第3次OldGC完成后Eden和Old区使用空间很多:,接着存放存活对象,触发了第4次OldGC,完成后回到程序初始运行状态,此时要晋升的对象有50M多点,又触发了OldGC

11、对JVM性能进行优化

分析这个程序,方法结束后所有的对象都是垃圾对象,也就是说一秒内分配的对象只要S区可以放下,那么下一秒就可以被回收了。此时需要增加S区的大小

参数配置:-XX:NewSize=200M-XX:MaxNewSize=200M-XX:InitialHeapSize=300M-XX:MaxHeapSize=300M-XX:SurvivorRatio=2-XX:MaxTenuringThreshold=15-XX:PretenureSizeThreshold=20M-XX:+UseParNewGC-XX:+UseConcMarkSweepGC-XX:+PrintGCDetails-XX:+PrintGCTimeStamps-Xloggc:d:/gc.log

Eden 100M,From To 50M这样就避免了FULLGC了,但YGC频繁没发避免的,因为每秒耗用的内存太多80M,但没关系,可以看看下图,一次YGC平均耗费4.5ms

本文是《从 0 开始带你成为JVM实战高手》内容总结,版权问题,特此声明。详细内容:

如果购买,成功后加QQ群找群主返现10元

054 JVM实战总结: 案例实战:每日百亿数据量的实时分析引擎 如何定位和解决频繁Full GC问题?

如果觉得《054 JVM实战总结: 案例实战:每日百亿数据量的实时分析引擎 如何定位和解决频繁Ful》对你有帮助,请点赞、收藏,并留下你的观点哦!

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