同样的java程序一个占用的cpu过高_java程序 cpu占用过高分析

linux终端下用 top命令看到cpu占用超过100%。之所以超过100%。说明cpu是多核。默认top显示的是cpu加起来的使用率,运行top后按大键盘1看看,可以显示每个cpu的使用率,top里显示的是把所有使用率加起来。如果是4核cpu占用率最高可达400%。

java进程占用CPU过高常见的两种情况及分析定位

在linux中的定位方法

4.1.找到CPU占用高的进程号 如:使用top命令查看(可以使用其它方法,只要找到对应的进程号即可)

注:图中第一列PID为进程号;

4.2、根据进程号找到CPU占用高的线程

如:使用命令top -H -p (其中要换成第一步找到的进程号)

top连接参数说明

-H :Threads-mode operation

Instructs top to display individual threads. Without this command-line option a summation of all threads in each process is shown. Later this can be changed with the `H' interactive command.

-p :Monitor-PIDs mode as: -pN1 -pN2 ... or -pN1,N2,N3 ...

Monitor only processes with specified process IDs. This option can be given up to 20 times, or you can provide a comma delimited list with up to 20 pids. Co-mingling both approaches is permitted.

1

2

查看某个进程内部线程占用情况分析:

top -H -p 18605

注:图中第一列PID此时为线程号;

4.3.导出java进程执行堆栈,并找到对应的线程

使用jstack > jstack_xxx.txt (其中要换成第一步找到的进程号)

从第二步中的PID中找出一个CPU占用高的线程号,把它转成16进制,比如3261转成CBD

从导出的堆栈信息里找到nid为cbd的线程堆栈

4.4:从堆栈里找到对应的代码执行类和方法

若代码为业务代码,则需要具体分析代码,找出代码中死循环或接近死循环的地方,并修正;定位结束;

若堆栈信息为gc线程(类似下图),则需要进行下一步

4.5:dump出java进程的堆对象使用情况

使用jmap -histo > jmap_xxx.txt

找出量比较大的、且跟业务有关的对象,找到这些对象创建的地方进行分析;一般需要持续创建大量的对象,使得内存不够用时,才会频繁触发gc进行回收,gc回收时jvm有停顿,CPU也占用很高。

线程之间的切换,是很耗费性能的,所以带来CPU飙升.

新生代设置过小,也会频繁触发gc。有大对象始终根节点路径可达,无法释放,jvm在疯狂的Full GC。

---------------------

一篇文章:

简单记录下对这个问题的跟踪

首先当然要看下具体是java中哪个线程一直在占用cpu时间哈(说明下, java进程号是 26178)

1.根据java进程ID进行CPU占用排查  ps -mp 26178 -o THREAD,tid,time | sort -rn | more  (sort -rn 以数值的方式进行逆序排列)

2.根据1中查找到的CPU最高的排序中的结果,找出几个占用cpu时间比较高的TID,比如这里的26217 26182 26183

将进程ID转换为16进制,printf "%x\n" 26217

3.再使用jstack命名查询是哪个线程

TID十进制-》十六进制

26217 -》 6669

26182 -》 6646

26183 -》 6647

拿到线程ID的16进制之后,就可以从jstack中查找具体是对应的线程

jstack 26178 |grep 6669 -A 30

可以发现,几个占用大量cpu时间的线程都是GC相关。

(grep -A:

Context control:

-B, --before-context=NUM print NUM lines of leading context

-A, --after-context=NUM print NUM lines of trailing context

找出filename中带有keyword的行,输出中除显示该行外,还显示之后的x行。其中,数字可以变。

-C, --context=NUM print NUM lines of output context

)

4.再次确认gc信息,查看gc time等信息,jstat -gcutil 26178 1000 100

可以看到s0、s1、eden、old、metaspace都已经爆了,并且FGC次数一直在增加,但是却没有回收到任何空间,导致FGC一直在跑,进入循环,应该是程序存在内存泄露咯。(gc有日志,后续有空再出一篇简单分析gc日志的blog)

5.jmap -histo:live 26178 | more  简单查看对象的大小数目

6.dump内存,使用工具分析内存镜像,jmap -dump:live,format=b,file=problem.bin 26178

7.使用MAT(Memory Analyzer tool)进行数据分析,注意,如果步骤6中dump出来文件过大,需要设置MAT配置文件(MemoryAnalyzer.ini)的xmx参数的大小。

---------------------

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值