jvm

今天处理了一次性能问题,记录一下处理的过程。
早上发现几台机器负载非常高,前端nginx的连接数接近2000。
后端的应用服务器的响应情况很忙,最糟糕的情况达到了30多万毫秒。
top看到进程运行情况:
PID USER      PR NI VIRT RES SHR S %CPU %MEM    TIME+ COMMAND 
3182 root      25   0 1028m 560m 9296 S 289.6 29.6 27:22.26 java         
3220 root      25   0 1039m 678m 9308 S 108.3 35.8 27:17.61 java         
    1 root      15   0 2084 608 524 S 0.0 0.0   0:55.82 init   
确定了是应用服务器程序占用了大部分cpu
接着运行top -H -p 3182
看到占用最高的cpu的java进程号。
jstack 显示该jvm进程中所有线程的调用栈已经线程所处的状态(jdk5.0以上支持)。
jstack pid | less 
查找上述进程号的十六进制数字,比如nid=0x1613d(小写)
找出对应的进程
java.lang.Thread.State: RUNNABLE
        at net.sf.json.util.JSONTokener.nextClean(JSONTokener.java:207)
        at net.sf.json.JSONObject._fromJSONTokener(JSONObject.java:1089)
        at net.sf.json.JSONObject._fromString(JSONObject.java:1311)
        at net.sf.json.JSONObject.fromObject(JSONObject.java:180)
        at net.sf.json.JSONObject.fromObject(JSONObject.java:149)
是这个JSON对象转换处理耗用了大量CPU,google了一下也没找到谁遇到相同的问题,于是google其他json转换的替换,找了这个文章,提到三个JSON Parser,基于他的测试,他得到的结果是:
test.
   1. Create a JSON object
   2. Add few String objects to the object
   3. Serialize and deserialize the JSON object
   4. Loop the above for 1 million times.

The performance of the above libraries sorted in order
   1. Jackson
   2. Noggit
   3. JSON-lib
找了第一个Jackson,比较庞大,放弃,找第二个Noggit,是apache下面一个开源的,代码简单,只有几个类。下载,打包,跑程序测试,性能比原来JSON lib 好上10倍以上。马上替换,服务器负载即刻下降,响应都在几十毫秒内,问题解决。

附这次搜索到相关的资料:
java内存检测的工具
Java 垃圾回收策略调优

其他指南:
查找内存泄露方法:
1.可以使用jdk6.0自带的工具
jps -l 可以查看当前机器上所有运行的java进程

[root@search1 srcStore]# jps -l   
5218 sun.tools.jps.Jps   
23979 com.test.commond.SrcStoreCommond   
24222 com.test.command.Crawler  

jinfo 命令显示指定的jvm进程所有的属性设置和配置参数:

jinfo 23979

jstack 命令显示指定的jvm进程中所有线程的调用栈已经线程所处的状态

jstack 23979  

可以利用hprof分析指定java应用程序内存使用和cpu使用。

比如查看内存方面,在启动应用时添加参数:

-agentlib:hprof=heap=sites,file=heap.txt  

当程序运行一段时间后,停止运行程序。

打开heap.txt. heap.txt的最后有内存占用大小排名顺序。

找到前几个排名。查看其对应的trace值. 然后在heap.txt里查找该track值对应的信息。

会查找到类似主要的

TRACE 306561:    
        java.util.HashMap$Entry.<init></init>(HashMap.java:683)    
        java.util.HashMap.addEntry(HashMap.java:753)    
        java.util.HashMap.put(HashMap.java:385)    
        com.mysql.jdbc.Connection.loadServerVariables(Connection.java:4321)  

可以定位到某个类的某行。

也可以查看cpu信息。只需要把应用启动时加一个参数:

-agentlib:hprof=cpu=samples,file=cpu.txt

Java进程占用CPU高的问题跟踪

posted on 2014-01-06 10:36  ukouryou  阅读(230)  评论(0编辑  收藏  举报

导航