JVM高CPU或高内存、堆外内存高分析
高CPU
1、查看那个线程消耗了CPU
top -Hp pid
或
ps -mp #pid -o THREAD,tid,time命令查看该进程的线程情况
ps p #pid -L -o pid,pcpu,tid,time,tname,cmd
ps -p #pid -L | awk -F ' ' '{print $5}' | sort | uniq -c | sort -k1 -nr
Linux下查询线程信息的其他方法
cd /proc/#pid/status
以及
cd /proc/#pid/task/#tid/status
2、找到线程号,将线程号转化为16进展
printf "%x\n" tid
3、获取详细的线程信息
jstack -l <pid> | grep <thread-hex-id> -A 50
注:针对不明显的CPU消耗,可以使用火焰图分析:性能火焰图的原理是通过采集应用程序的性能数据,将其转换为可视化的火焰图形式,即在【一段时间内】、【指定采样频率】 下采集CPU的使用情况,形成统计图,参考【性能调优利器:火焰图】
高内存
1、查看堆配置
jmap -heap pid
查看统计内部对象情况:这种情况下可使用jmap 结合 -histo参数以及linux sort命令 以对jvm最小影响提取heap概况。使用-histo:live 将触发gc
2、统计实例排名前10的类:
jmap -histo pid | sort -n -r -k 2 | head -10
3、统计总计容量排名前10的类:
jmap -histo pid | sort -n -r -k 3 | head -10
4、生成dump文件,使用mat分析(live的选项,实际上是产生一次Full GC来保证只看还存活的对象。有时候也会故意不加live选项,看历史对象。)
jmap -dump:live,format=b,file=/heapdump/xxx.hprof <pid>
压缩
tar -cvzf aaaa.tar.gz java_pid.hprof
5、使用MAT工具查看Dump文件
堆外内存过高案例(Glibc 64M问题)
1、top 命令查看当前的使用情况
top
2、查看内存使用情况:pmap
pmap -x $pid | sort -k 3 -n -r | head -10
或
pmap -x $pid | grep anon | sort -k 3 -n -r | head -10
3、Linux下glibc的内存管理机制用了一个很奇妙的东西,叫arena。在glibc分配内存的时候,大内存从从中央分配区分配,小内存则在线程创建时,从缓存区分配。为了解决分配内存的性能的问题,就引入了这个叫做arena的memory pool。而恰好,在64bit系统下面,它的缺省配置为64M。一个进程可以最多有cores*8个arena,假如服务器是4核的,那么最多有4*8=32个arena,也就是32*64 = 2048M内存。然而,为了满足业务,我这台服务器居然是12核的,单单一个进程的arena占用的内存就达到了6G。
4、修改启动脚本,添加限制
export MALLOC_ARENA_MAX=1
# 查看 glibc 版本
ldd --version
#查看进程当前的环境变量值
grep MALLOC_ARENA_MAX /proc/$pid/environ
cat /proc/<pid>/environ
# 该命令的输出格式不太容易读,所有的信息挤在了同一行。使用 tr 命令将空字符替换为换行符,将会使所有的环境变量按行显示:
cat /proc/<pid>/environ | tr "\\0" "\\n"
#或
cat /proc/<pid>/environ | tr '\0' '\n'
- 点赞
- 收藏
- 关注作者
评论(0)