jvm性能调优

最近有两个系统先后被恶意扫描,出现 CPU 使用率高的现象。很好,把问题暴露出来解决掉。

CPU 使用率很高,首先是要找出 CPU 在执行什么样的代码,然后在分析这些代码有什么问题。

一、问题定位

1、  用命令 “ps aux | grep APP” 找出应用的进程 id:

801       84703  5.6 28.8 4627436 1132100 pts/2 Sl   11:08  11:19 /usr/jdk1.6.0_38/bin/java APP

2、  找出耗CPU的线程,在Linux系统下用命令:“ top  –H  –p  pid  ”, pid 就是前面找出来的应用进程 ID 。这个命令会显示出当前占用CPU高的线程。

Tasks: 426 total,   0 running, 426 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.5%us,  0.6%sy,  0.0%ni, 72.3%id, 26.6%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   3924912k total,  3308088k used,   616824k free,      768k buffers
Swap:  8388600k total,  3236720k used,  5151880k free,    12304k cached

   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
84784 appdeplo  20   0 4518m 1.1g 3816 S  0.4 29.0   0:00.85 java
84903 appdeplo  20   0 4518m 1.1g 3816 S  0.4 29.0   0:34.66 java
84983 appdeplo  20   0 4518m 1.1g 3816 S  0.4 29.0   0:00.99 java
85091 appdeplo  20   0 4518m 1.1g 3816 S  0.4 29.0   0:02.69 java
85164 appdeplo  20   0 4518m 1.1g 3816 S  0.4 29.0   0:04.92 java
84703 appdeplo  20   0 4518m 1.1g 3816 S  0.0 29.0   0:00.00 java
84704 appdeplo  20   0 4518m 1.1g 3816 S  0.0 29.0   0:00.42 java
84705 appdeplo  20   0 4518m 1.1g 3816 S  0.0 29.0   0:02.52 java
84706 appdeplo  20   0 4518m 1.1g 3816 S  0.0 29.0   0:02.64 java
84707 appdeplo  20   0 4518m 1.1g 3816 S  0.0 29.0   0:02.46 java
84708 appdeplo  20   0 4518m 1.1g 3816 S  0.0 29.0   0:02.39 java
84709 appdeplo  20   0 4518m 1.1g 3816 S  0.0 29.0   0:33.99 java

这里的 PID 比如 84784 是十进制的,需要转换为十六进制,用windows的计算器就可以转换了,转换为十六进制是:14B30

3、  dump 出进程的所有线程栈,用命令 “./jstack -F -m -l 84703 > 84703.stack” 84703 是 pid。
dump出的其中一个线程栈大概是这样的:

"container-332" prio=10 tid=0x00007f4a044fa800 nid=0x13c7a runnable [0x00007f46e4ec8000]
   java.lang.Thread.State: RUNNABLE
         at java.net.SocketInputStream.socketRead0(Native Method)
         at java.net.SocketInputStream.read(SocketInputStream.java:129)
         at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
         at java.io.BufferedInputStream.read(BufferedInputStream.java:237)
         - locked <0x0000000709252728> (a java.io.BufferedInputStream)
         at java.io.DataInputStream.readInt(DataInputStream.java:370)
         at com.ibm.mq.MQInternalCommunications.timedReadInt(MQInternalCommunications.java:2748)
         at com.ibm.mq.MQInternalCommunications.receiveBytesFaster(MQInternalCommunications.java:2846)
         - locked <0x00000007092524e0> (a com.ibm.mq.MQv6InternalCommunications)
         at com.ibm.mq.MQInternalCommunications.receive(MQInternalCommunications.java:1179)
         - locked <0x00000007092524e0> (a com.ibm.mq.MQv6InternalCommunications)
         at com.ibm.mq.MQSESSIONClient.lowLevelComms(MQSESSIONClient.java:2841)
         - locked <0x0000000709252e10> (a java.lang.Integer)
         at com.ibm.mq.MQSESSIONClient.MQGET(MQSESSIONClient.java:1852)
         at com.ibm.mq.MQQueue.getMsg2Int(MQQueue.java:1217)
         - locked <0x0000000760c4c738> (a com.ibm.mq.MQSPIQueue)
         at com.ibm.mq.MQQueue.getMsg2(MQQueue.java:1074)
         - locked <0x0000000760c4c738> (a com.ibm.mq.MQSPIQueue)
         at com.ibm.mq.jms.MQMessageConsumer.getMessage(MQMessageConsumer.java:3451)
         at com.ibm.mq.jms.MQMessageConsumer.receiveInternal(MQMessageConsumer.java:2866)
         at com.ibm.mq.jms.MQMessageConsumer.receive(MQMessageConsumer.java:2669)
         at com.ibm.mq.connector.outbound.MessageConsumerWrapper.receive(MessageConsumerWrapper.java:180)
         at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveMessage(AbstractPollingMessageListenerContainer.java:429)
         at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:310)
         at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:263)
         at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1058)
         at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1050)
         at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:947)
         at java.lang.Thread.run(Thread.java:662)

第一行的 nid 就是前面转换出来的十六进制数字,所有线程都有这样的对应线程栈。线程dump文件是文本文件,直接用文本编辑器查看就可以了。从上面的线程栈,我们就可以看到占用cpu高的线程在做什么。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值