今天处理了一次性能问题,记录一下处理的过程。
早上发现几台机器负载非常高,前端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