0
点赞
收藏
分享

微信扫一扫

JVM Dump方法以及内存泄漏分析方法

老王420 2022-03-30 阅读 70
性能优化

一、自动生成Dump(JMX的MBean)

JVM启动参数配置:

-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/home/app/dumps/

二、手动生成Dump

jmap -dump:format=b,file=../dump/testdump0329.hprof 9018

三、内存泄漏分析

1、查看大对象,并梳理调用关系(VisualVM、JProfile、MAT)

2、查看

崩溃前垃圾回收的时间越来越长

四、性能调优

1、线程池:

2、连接池:程序逻辑算法优化(95%的场景通过此方法解决)

3、JVM启动参数:调整各代内存比率和垃圾回收算法、提高吞吐

a、GC时间足够小

b、GC次数足够少

c、FullGC频率足够低

a和b有一定冲突,一般为避免最大最小之间收缩产品额外gc,最大最小设置相同,yong与old比率1:2,NewRadio调整比率,为防止年轻代堆收缩,-XX:newSize -XX:MaxNewSize一样大小,

更大年轻代,更小老年代,大的年轻代会延长普通GC周期,但会增加每次GC的时间;小的年老代会导致更频繁的FullGC;

更小的年轻,更大老年代,小的年轻代会导致普通GC频繁,每次GC时间短,大的年老代减少FullGC频率;

如何选择应该依赖应用程序对象生命周期的分布情况:如果应用存在大量的临时对象,应该选择更大的年轻代;如果存在相对较多的持久对象,年老代应该适当增大。但很多应用都没有这样明显的特性,在抉择时应该根据以下两点:(A)本着Full GC尽量少的原则,让年老代尽量缓存常用对象,JVM的默认比例1:2也是这个道理 (B)通过观察应用一段时间,看其他在峰值时年老代会占多少内存,在不影响Full GC的前提下,根据实际情况加大年轻代,比如可以把比例控制在1:1。但应该给年老代至少预留1/3的增长空间

在配置较好的机器上(比如多核、大内存),可以为年老代选择并行收集算法: -XX:+UseParallelOldGC ,默认为Serial收集

线程堆栈的设置:每个线程默认会开启1M的堆栈,用于存放栈帧、调用参数、局部变量等,对大多数应用而言这个默认值太了,一般256K就足用。理论上,在内存不变的情况下,减少每个线程的堆栈,可以产生更多的线程,但这实际上还受限于操作系统

可以通过下面的参数打Heap Dump信息

  • -XX:HeapDumpPath
  • -XX:+PrintGCDetails
  • -XX:+PrintGCTimeStamps
  • -Xloggc:/usr/aaa/dump/heap_trace.txt

请看一下一个时间的Java参数配置:(服务器:Linux 64Bit,8Core×16G)

 JAVA_OPTS="$JAVA_OPTS -server -Xms3G -Xmx3G -Xss256k -XX:PermSize=128m -XX:MaxPermSize=128m -XX:+UseParallelOldGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/aaa/dump -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:/usr/aaa/dump/heap_trace.txt -XX:NewSize=1G -XX:MaxNewSize=1G"

经过观察该配置非常稳定,每次普通GC的时间在10ms左右,Full GC基本不发生,或隔很长很长的时间才发生一次

通过分析dump文件可以发现,每个1小时都会发生一次Full GC,经过多方求证,只要在JVM中开启了JMX服务,JMX将会1小时执行一次Full GC以清除引用,关于这点请参考附件文档

4、程序算法:程序逻辑算法优化

参考资料:

JVM性能调优之生成堆的dump文件_iTry的博客-CSDN博客_堆dump

举报

相关推荐

0 条评论