1.find the jvm process
ps aux | grep java
tomcat 26551 128 30.9 3946348 1215360 ? S1 13:43 26:21 /usr/java/latest
2. generate thread dump of the java main thread found in step 1
JVM main thread = Linux process,other java threads = Lightweight process(LWP)
jstack 26551 > threaddump.log
3. find suspect lightweight processes(LWPS) with high cpu usage
top -H
第一行:整体运行情况
top - 13:59:28 up 29days,11:16, 1 user, load average:5.15, 4.75, 3.38
13:59:28:当前系统时间(在这期间没有重启过)
up 29days:系统已经运行的时间
1 user: 当前登录用户的数量
load average:5.15, 4.75, 3.38:1分钟,5分钟、15分钟系统平均负载
load average数据是每隔5秒钟检查一次活跃的进程数,然后按特定算法计算出的数值。 如果这个数除以逻辑CPU的数量,结果高于5的时候就表明系统在超负荷运转了。
第二行:任务
Task:512 total, 8 running,504 sleeping 0 stopped, 0 zombie
512 total:共147个任务(进程)
8 running:有8个任务(进程)正在运行
504 sleeping:有145个任务(进程)正在睡眠
0 stopped:有0个任务(进程)已经停止
0 zombie:有0个僵尸任务(进程)
第三、四行:CPU
Cpu0 84.9%us, 9.4%sy, 0.0%ni, 3.7%id, 0.7%wa,0.0%hi, 1.3%si, 0.0%st
Cpu1 84.7%us, 8.0%sy, 0.0%ni, 5.0%id, 0.7%wa,0.0%hi, 1.7%si, 0.0%st
us:运行(未调整优先级的)用户进程所占的cpu时间(百分比)
sy:运行系统内核进程所占的cpu时间(百分比)
ni:运行用户进程(已经调整优先级的)进程所占的CPU时间(百分比)
负值表示高优先级,正值表示低优先级
id:空闲进程所占的cpu时间(百分比)
wa:用于等待IO完成所占的cpu时间(百分比)
hi: 硬件中断
si: 软件中断
st:实时
第五行:内存
Mem: 3924512K total, 378434k Ok used, 140172k free, 148876k bufferes
物理内存:全部内存 已使用内存 空闲内存 缓冲内存
第六行:swap交换分区
交换区内存:交换区总量使用的交换区总量空闲交换区总量缓冲的交换区总量
如果出于习惯去计算可用内存数,这里有个近似的计算公式:第四行的free + 第四行的
buffers + 第五行的cached,按这个公式此台服务器的可用内存:
530668+79236+4231276 = 4.7GB。
对于内存监控,在top里我们要时刻监控第五行swap交换分区的used,如果这个数值在
不断的变化,说明内核在不断进行内存和swap的数据交换,这是真正的内存不够用了。
其他行的LWPS数据
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ command
26605 tomcat 20 0 3853m 1.1g 12m R 32.2 29.8 3:10.85
PID:进程ID
USER: 进程所有者的实际用户名
PR:进程的调度优先级。这个字段的一些值是rt,这意味着这些进程运行在实时态
NI:进程的nice值(优先级),越小的值意味着越高的优先级
VIRT:进程使用的虚拟内存
RES:驻留内存大小。驻留内存时任务使用的非交换物理内存大小
SHR:进程使用的共享内存
S:进程的状态
D - 不可中断的睡眠态
R - 运行态
S - 睡眠态
T - 被跟踪或已停止
Z - 僵尸态
CPU:从上一次更新时到现在任务所使用的CPU时间百分比
MEM:进程使用的可用物理内存百分比
TIME:任务启动后到现在所使用的全部CPU时间,精确到百分之一秒。
COMMAND:运行进程所使用的命令
It can be observed there are tow LWPs using 32% and 14% of the cpu
where the rest stays around the the same percentage
4.conver LWP IDS from decimal to hexadecimal for pids with high cpu usage
Decimal hexadecimal(将十进制转十六进制)
26605 67ED
26602 67EA
5.open threaddump from step 2 and locate hex value 0x67ed and 0x67ea
6.troubleshoot
From previous stack trace examples,seems high CPU usage is related to log4j async appender,
In this case very likely involving PCIPatternLayout.format() method.
7.另外可考虑客户端请求书是否过大
监控网络客户连接数:
netstat -n | grep tcp | grep 侦听端口 | wc -l
引用资料:
http://tech.asimio.net/2016/02/11/Troubleshoot-high-CPU-usage-in-Java-applications.html