一、JVM资源
1. 线程
操作系统线程:CPU调度单位
计数器:线程运行到哪行代码了
运行栈:线程运行在哪个方法,局部变量有哪些,都是什么
2. 内存
堆:new 出来的对象基本都在这里,有些删的快有些删的慢所以分为有young和old,两个分别回收垃圾,有指针指向的对象[级联判定]不会被回收
xms:堆大小下限
xmx:堆大小上限
NewRatio:old:young比例,默认2:1
SurvivorRatio:young区内伊甸区与两个生存区比例,默认8:1:1
栈:
计数器:
堆外等:
二、工具
这里以clbs所属进程的pid为1234举例,本文仅介绍常用用法,详细内容此处不再展开,后续用到时自行上网搜索。
1. less
less error.log
方向键、PageUp、PageDown
命令同vi,常用:
gg文件开始
G 文件末位
/abc 从光标处向下正则搜索abc字符
?abc 从光标处向上正则搜索abc字符
n 搜索下一个
N 搜索上一个
2. top
主界面核心关注:
CPU(us[用户程序占用CPU]、wa[CPU等待磁盘或网络IO])
负载[CPU+IO综合指标,小于核数为正常]
内存(free+buff)
%CPU最高线程
RES[内存实际使用值KB]最高线程
h 帮助
c 显示/隐藏命令
M 按内存排序
top -Hp 1234 显示clbs每个线程的CPU使用情况
3. jstack
jstack 1234 > clbs.tdump && less tdump 保存并查看jvm线程栈
提示无响应时可尝试增加参数 -F 强制执行
4. jstat
jstat -gc 1234 查看内存各区域使用大小和gc统计
jstat -gcutil 1234 查看内存各区域使用百分比和gc统计
5. jmap
jmap -heap 1234 查看堆内存使用情况
jmap -dump:format=b,file=clbs_0423.hprof 1234 转储堆内存到文件,然后压缩下载回本地分析
提示无响应时可尝试增加参数 -F 强制执行
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/tomcat-clbs/clbs.hprof
6. jinfo
jinfo 1234 查看运行环境和jvm参数
7. jcmd
jcmd 1234 help 显示可用命令
jcmd 1234 Thread.print 同jstack
jcmd 1234 GC.heap_dump clbs_0423.hprof 1234 同jmap
8. netstat
协议-接收队列-发送队列-源-目标-状态-进程
netstat -anpt | grep 1234 显示所有tcp连接
netstat -lntp | grep 1234 显示所有监听端口
9. MAT
记得在设置中勾选Keep unreachable objects
打开hprof文件,分析oom时首选Leak Suspects,分析所列最大对象中的内容
list outgoing: 查看选中对象引用的对象
list incoming: 查看引用了选中对象的对象
这里以A B C D类举例,对象分别是a b c d,引用关系是 a → b b → c d → c
Shallow size:对象本身大小,不含它引用的对象:a
Retained size:对象本身及它引用的对象的大小(级联),但其中的共享对象除外:a + b
Deep size:对象本身及它引用的对象的大小(级联):a + b + c
共享对象:除了被当前对象所有引用的对象(级联)引用之外,还被其他对象引用:统计a时,c就算共享对象
10. JProfiler
分析hprof时与MAT类似,但推荐使用MAT
内网实时分析、全面分析、持续分析场景建议使用JProfiler
11. https://gceasy.io
分析GC日志,稳定运行时,old和metaspace不应该逐渐上升
根据运行过程中的young、old占用百分比和gc,以及中断时间、频率,来设置newRatio和survivorRatio
12. GDB
当生产环境出事故需要尽快恢复时,使用gdb命令保存现场(最好同时保存tdump和gc.log),然后慢慢导出堆内存等信息
gdb -pid 1234
(gdb) gcore /home/tomcat-clbs/clbs_0423.core.1234
(gdb) detach
(gdb) quit
分析core.1234:https://cloud.tencent.com/developer/article/1407569
使用 which java 命令查询jdk路径(注意要和tomcat进程使用的java版本号一致,gdb命令也会打印路径),这里以/usr/jdk64/jdk1.8.0_131/bin/java举例:
/usr/jdk64/jdk1.8.0_131/bin/jmap -dump:format=b,file=/home/tomcat-clbs/clbs_0421.hprof /usr/jdk64/jdk1.8.0_131/jre/bin/java /home/tomcat-clbs/clbs_0423.core.1234
三、现象
1. oom:heap
gdb保存进程
备份gc日志
jstack -F
重启
jmap生成堆文件
2. 端口堵塞
netstat分析端口/进程
如遇未知端口,搜索代码中该端口所属功能
消费类:检查线程栈是否包含该功能相关线程,如果有,运行到哪行代码,如果无,分析挂掉原因
连接类:分析线程栈同功能使用情况,结合堆内存分析原因
3. 高CPU占用
top命令查看异常进程及pid,同时观察内存消耗情况
top -Hp 1234 查看该进程占用CPU最高的线程id
如果是jvm,使用jstack分析(jstack里的线程id是16进制的,注意用计算器转换或用printf '%x\n' 1234命令来转换)
4. 高内存占用
jinfo查看xmx MaxMetaSpace参数
jstat查看gc情况,可结合gc日志,判断有无泄漏嫌疑
如老年代占用高,使用jmap转储堆内存分析
是堆大小设置太小还是内存泄漏,然后进行调整或修复
5. 高负载
检查CPU占用
检查磁盘IO
检查网络IO