工具命令
# 1 jmap
jps
14660 jar
jmap -histo 14660 > ./log.txt
此命令可查看内存信息,实例个数以及占用内存大小
jmap -heap 14660
查看堆信息
jmap -dump:format=b,file=test.hprof 14660
也可以设置内存溢出自动导出dump文件(内存很大的时候,可能会导不出来)
1.-XX:+HeapDumpOnOutOfMemoryError
2.-XX:HeapDumpPath=./ (路径)
# 2 jstack
找出占用cpu最高的线程堆栈信息
top
top -p 24
按H,获取每个线程的内存情况
1.找到内存和cpu占用最高的线程pid,比如797,转换成16进制得到0x31D
2.执行jstack 24 | grep -A 10 31D
# 3 jinfo
jinfo -flags 24
查看jvm的参数
# 4 jstat
jstat -gc 24
jstat -gc pid 最常用,可以评估程序内存使用及gc压力整体情况
可以执行命令 jstat -gc pid 1000 10 (每隔1秒执行1次命令,共执行10次),通过观察EU(eden区的使用)来估算每秒eden大概新增多少对 象,如果系统负载不高,可以把频率1秒换成1分钟,甚至10分钟来观察整体情况。
S0C:第一个幸存区的大小,单位KB
S1C:第二个幸存区的大小
S0U:第一个幸存区的使用大小
S1U:第二个幸存区的使用大小
EC:伊甸园区的大小
EU:伊甸园区的使用大小
OC:老年代大小
OU:老年代使用大小
MC:方法区大小(元空间)
MU:方法区使用大小
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间,单位s
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间,单位s
GCT:垃圾回收消耗总时间,单位s
优化思路其实简单来说就是尽量让每次Young GC后的存活对象小于Survivor区域的50%,都留存在年轻代里。尽量别让对象进入老年 代。尽量减少Full GC的频率,避免频繁Full GC对JVM性能的影响。
内存泄漏的一种情况:一般电商架构可能会使用多级缓存架构,就是redis加上JVM级缓存,大多数同学可能为了图方便对于JVM级缓存就 简单使用一个hashmap,于是不断往里面放缓存数据,但是很少考虑这个map的容量问题,结果这个缓存map越来越大,一直占用着老 年代的很多空间,时间长了就会导致full gc非常频繁,这就是一种内存泄漏,对于一些老旧数据没有及时清理导致一直占用着宝贵的内存 资源,时间长了除了导致full gc,还有可能导致OOM。