分析须知
应用cpu占用过高(执行机器单进程占用不到10%可视为正常),在不存在内存溢出的情况下,是不需要分析内存使用情况的
cpu占用过高说明应用的某一个处理过程占用cpu的时间比较长,最常见的情况是长时间的循环造成的
存在循环的逻辑尽量抽离出来作为单独的方法比较方便定位长循环
1.查询appname服务的进程pid【weblogic服务:Dweblogic.Name=Server-appname,普通的jar应用appname.jar】
ps -ef | grep appname
示例结果
例如
zyb 18972 18922 1 09:28 pts/2 00:05:39 /usr/java/jdk1.7.0_80/bin/java -server -Xms1024m -Xmx1024m -XX:MaxPermSize=512m
-Dweblogic.Name=Server-appname
2.显示 appname 进程18972下所有线程的cpu占用时间最多排序
ps -mp 18972 -o THREAD,tid,time|sort -rn| head -n 5
示例结果
例如
zyb 1.0 - - - - - - 00:05:39
zyb 0.2 19 - futex_ - - 19010 00:01:28
zyb 0.1 19 - futex_ - - 18988 00:00:39
zyb 0.1 19 - futex_ - - 10179 00:00:00
zyb 0.0 19 - skb_re - - 18981 00:00:00
3.选择需要查询线程号19010等,转为16进制
printf '%x\n' 19010
4a42
4.查询java线程栈信息(当前行及后30lines)
jstack 18972 | grep 4a42 -A 30
实际案例1
循环处理数据没有跳出循环
严重等级:极其严重,是完全错误的业务逻辑,一般应用不可能有这样的设计
通讯等待自定义循环获取流可读状态直到被关闭
严重等级:极其严重,是完全错误的技术应用逻辑,流的读写状态获取并不重要,jvm会使用操作系统的线程管理挂起等待响应的通信停止cpu占用,直到当前线程有流写入的响应中断再次占用cpu激活线程
内存占用分析
分析须知
应用内存占用过高,一般是部分实例化的对象在内存回收处理进行的情况下一直没有被销毁从而占用内存空间,对于应用的持续运行的稳定性存在威胁
系统一般在性能测试的大交易量积压下会比较块的暴露内存占用过高甚至是内存溢出
一般有两种思路
直接内存占用分析
内存占用明显异常的情况下,使用jmap命令获取应用进程的内存镜像
在memory Analysis的分析工具下查看内存实例的占用分布情况
实时监控分析内存
jvisualvm等工具支持本地及远程的服务进程分析
支持实例化对象的查询语法,更加精确的分析具体对象的实例化情况