jvm调优入门

背景

作为java主要开发人员,同时兼具项目部署在工作中难免遇到服务器资源,特别是内存消耗优化的问题,日常之谈,遇到了就会加上来,更多详细的信息可以参考阿里专业jvm调优大神的公众号‘你假笨’.

第一步使用top命令查看CPU占用率

centos中分析java占用大量内存的java代码,命令如下。
1:在命令行提示符执行top命令
2:输入大写P,则结果按CPU占用降序排序。输入大写M,结果按内存占用降序排序。(注:大写P可以在capslock状态输入p,或者按Shift+p)

PID(Process ID):进程标示号 ( 每个 process 的 ID )
USER:进程所有者的用户名 ( 该 process 所属的使用者 )
PR:进程的优先级别 ( Priority 的简写,程序的优先执行顺序,越小越早被执行 )
NI:进程的优先级别数值 ( Nice 的简写,与 Priority 有关,也是越小越早被执行 )
VIRT:进程占用的虚拟内存值。
RES:进程占用的物理内存值。
SHR:进程使用的共享内存值。
S:进程的状态,其中S表示休眠,R表示正在运行,Z表示僵死状态,N表示该进程优先值是负数。
%CPU:该进程占用的CPU使用率。
%MEM:该进程占用的物理内存和总内存的百分比。
TIME+:该进程启动后占用的总的CPU时间 ( CPU 使用时间的累加 

主要关注的字段,PID,RES,%CPU,%MEM

可以根据看到pid
根据PID可以查询cpu和内存使用的具体PID

根据PID找到CPU占用最高的TID并转换成16进制

根据第步找到该进程后,就要定位具体线程或代码,首先显示线程列表,并按照CPU占用高的线程排序:
ps -mp 16871 -o THREAD,tid,time | sort -rn

显示结果如下:
USER %CPU PRI SCNT WCHAN USER SYSTEM TID TIME
root 90.5 19 – – – – 14065 01:16:48
root 90.1 19 – – – – 14067 01:02:16
找到了耗时最高的线程9521,占用CPU时间有1个多小时了。frown
将需要的线程ID转换为16进制格式:
printf “%x\n” 14065
36f1

最后PID,TID使用jvm命令打印线程的堆栈信息:

jstack 16871 |grep 36f1 -A 30
这样就找到占用java,cpu资源的代码了,接下来还得分析代码执行的原因了。

"GC task thread#0 (ParallelGC)" prio=10 tid=0x00007fa35001e800 nid=0x36f1 runnable 
"GC task thread#1 (ParallelGC)" prio=10 tid=0x00007fa350020800 nid=0x36f2 runnable 
"GC task thread#2 (ParallelGC)" prio=10 tid=0x00007fa350022800 nid=0x36f3 runnable 
"GC task thread#3 (ParallelGC)" prio=10 tid=0x00007fa350024000 nid=0x36f4 runnable 
"GC task thread#4 (ParallelGC)" prio=10 tid=0x00007fa350026000 nid=0x36f5 runnable 
"GC task thread#5 (ParallelGC)" prio=10 tid=0x00007fa350028000 nid=0x36f6 runnable 
"GC task thread#6 (ParallelGC)" prio=10 tid=0x00007fa350029800 nid=0x36f7 runnable 
"GC task thread#7 (ParallelGC)" prio=10 tid=0x00007fa35002b800 nid=0x36f8 runnable 
"VM Periodic Task Thread" prio=10 tid=0x00007fa3500a8800 nid=0x3700 waiting on condition 

JNI global references: 392

GC task thread (ParallelGC)可以看出是堆内存占用率过高,ParallelGC是垃圾回收器的类型是用来给新生代做GC的。

使用jstat -gcutil命令查看进程的内存情况

打印TID的堆栈快照

[ylp@ylp-web-01 ~]$ jstat -gcutil 14063 2000 10

S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT   
0.00   0.00 100.00  99.99  26.31     42   21.917   218 1484.830 1506.747
0.00   0.00 100.00  99.99  26.31     42   21.917   218 1484.830 1506.747
0.00   0.00 100.00  99.99  26.31     42   21.917   219 1496.567 1518.484
0.00   0.00 100.00  99.99  26.31     42   21.917   219 1496.567 1518.484
0.00   0.00 100.00  99.99  26.31     42   21.917   219 1496.567 1518.484
0.00   0.00 100.00  99.99  26.31     42   21.917   219 1496.567 1518.484
0.00   0.00 100.00  99.99  26.31     42   21.917   219 1496.567 1518.484
0.00   0.00 100.00  99.99  26.31     42   21.917   220 1505.439 1527.355
0.00   0.00 100.00  99.99  26.31     42   21.917   220 1505.439 1527.355
0.00   0.00 100.00  99.99  26.31     42   21.917   220 1505.439 1527.355

从输出信息可以看出,Eden区内存占用100%,Old区内存占用99.99%,Full GC的次数高达220次,并且频繁Full GC,Full GC的持续时间也特别

分析堆栈

使用jstat命令查看进程的堆栈情况,需要把快照保存到本地

jstat 14063 >>jstat.out

拿到本地后,用编辑器查找带有项目并且线程状态是RUNABLE的相关的堆栈信息,从图中可以看出ActivityUtil.java类的447行正在使用HashMap.put()方法
在这里插入图片描述
修改或者优化代码逻辑,重新打包发布版本,使用相同条件重测。

这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值