Java虚拟机六:Java进程占用cpu过高问题分析

  在平时开发过程中,经常会碰到Java进程占用cpu过高的现象,本篇将简单记录一下自己分析该类问题的步骤。

  1.使用 top -p <pid> 命令(<pid>为Java进程的id号)查看Java进程的cpu占用:

  

  该Java进程占用cpu达到92.2%。

  2.使用 top -Hp <pid>  命令(<pid>为Java进程的id号)查看该Java进程内所有线程的资源占用情况(按shft+p按照cpu占用进行排序,按shift+m按照内存占用进行排序)此处按照cpu排序:

  

  可以看到,有两个线程号为97243,97912的线程占用cpu分别达到了69.2%和22.0%

  3.使用 printf "%x\n" <tid>  命令(tid指线程的id号)将以上10进制的线程号转换为16进制:

  

  转换后的结果分别为17bdb,17e78,由于16进制以0x开头,所以对应的16进制的线程号为0x17bdb和0x17e78。

  4.使用dk自带命令jstack获取此时的线程快照并输入到文件中: jstack -l <pid> > ./jstack_result.txt 命令(<pid>为Java进程的id号)来获取线程快照结果并输入到指定文件。

  5.查看第4步生成的txt文件,在其中搜索tid为0x17bdb的线程:

  

  可以看到线程号为0x17bdb(10进制线程号97243)对应的是一个"VM Thread"即虚拟机线程,这个不是与我们代码相关的线程,所以暂时忽略。

  再看0x17e78线程:

  

  该线程的堆栈较深,且很明显有调用我们自己代码的逻辑,并且提示了具体的代码行数,我们查看该处代码:

  

  发现此处是在一个死循环里边重复的拼接字符串导致的,我们知道,String类使用contact方法拼接字符串其实是创建新的对象并返回,看到这里,似乎可以和占用cpu最高的"VM Thread"联系起来了,因此作出假设:由于代码一直循环创建对象,导致不断有不再被引用的对象产生,虚拟机检测到对象不再被引用之后,就进行垃圾回收,垃圾回收占用了很大一部分cpu资源。

  为了证明该假设,设置jvisualvm监控,经过一段时间允许,cpu资源监控结果如下:

  

  可以看到cpu总占用达到88.5%,而垃圾回收活动占用cpu达到84.0%,因此证明了上述假设。

  知道了该问题的原因后,我们还想知道此时垃圾回收的频率,耗时等信息,于是可以设置JVM参数 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:./gc.log (或者使用jinfo命令动态设置GC日志,可参考http://www.importnew.com/15722.html),可以看到日志内容:

   

  gc.log中频繁的打印垃圾回收,不过我们看到的基本都是Minor GC,即新生代的垃圾回收。

  为了更清晰的查看各个区的垃圾回收情况,可以使用jstat命令 jstat -gc <pid> <period> <count>  (pid为Java进程的id,period指每次监控之间的时间间隔,count指监控次数)来监控垃圾回收,打印内容如下:

  

  可以看到,虚拟机在进行频繁的Full GC,每次耗时均在增长。

  总结:

  分析Java进程占用cpu过高问题时候,基本都可以按照如下步骤进行分析:

  (1)使用 top -Hp <pid> 命令找出进程中占用cpu最高的前几个线程

  (2)使用jstack获取线程快照,然后使用线程id搜索分析快照文件

  (3)如果线程调用了业务相关代码,则分析是否是代码问题导致的cpu占用过高,如果线程是VM Thread,则应该监控检查垃圾回收活动频率,看是否是因为频繁进行垃圾回收导致的。

  

  

原文地址:https://www.cnblogs.com/fengweiweicoder/p/10992043.html

时间: 2024-10-14 04:03:30

Java虚拟机六:Java进程占用cpu过高问题分析的相关文章

tomcat7+java压测过程中占用CPU过高排查故障和解决办法

环架构境: 前端haproxy做为反向代理,后端N+1台tomcat+java服务 出现问题: 环境是新搭建的,本周在做压测刚开始的时候正常,随着量的上涨,导致CPU一直暴涨. 解决办法和思路: 1.)先通过top命令查看占用cpu高的PID # 根据top命令查看发现PID为2195和975的的进程占用CPU高达%200+,明显出现故障 2.)通过top -H -p pid命令查看,发现2275 3302 3375这几个进程占用CPU时间8分钟 3.)把线程pid转换为16进制,例如:上面的p

PHP CGI 进程占用CPU过高导致CPU使用达到100%的另类原因

由于使用的华为云的CDN加速,结果发现我的阿里云服务器突然卡顿,网页打开极慢.登陆华为云CDN管理后台发现最高带宽占用30M,流量短时间内达到10GB以上,这么大的流量我的服务器肯定扛不住啊.于是还跟华为云进行了一个撕逼,然后果断弃了华为云. 但是更换了其他CDN或者WAF之后,CPU占用依然居高不下,网上找了很多办法都不管用. 看了下是 PHP CGI 进程占用CPU最多,而且经过检测发现是 浏览器内核检测 网站的 PHP CGI 占用最高,其他的很少.然而看第三方网站统计,并没有很大的访问量

linux 分析进程占用CPU过高

重点是查看进程的线程中,哪个线程占用cpu过高,然后用gdb附加到进程,调试线程,看是否有死循环或者死锁等问题,步骤如下: 1 先用ps + grep找出该死的进程pid,比如 1706 2 top -H -p 1706,(top然后shift+H可以看出某个线程,左上角有提示:thread on 则为可查看线程)所有该进程的线程都列出来, 看看哪个线程pid占用最多,记下对应的线程号,如:1723 gdb attach 到进程号码(1706) (仍然在gdb中) info threads 结果

java进程占用cpu过高分析是哪些线程

拿hbase基准测试列子来分析哪些线程使用比较高的cpu,环境是linux,基准测试命令: hbase org.apache.hadoop.hbase.PerformanceEvaluation  --rows=500000 --nomapred --presplit=5 --writeToWAL=true randomWrite 5 首先查看占用cpu最高的进程和线程id,执行命令: [[email protected] logs]$ ps Hh -eo pid,tid,pcpu | sort

linux下查找java进程占用CPU过高原因

1. 查找进程 top查看进程占用资源情况 明显看出java的两个进程22714,12406占用过高cpu. 2.查找线程 使用top -H -p <pid>查看线程占用情况 3.查找java的堆栈信息 将线程id转换成十六进制 #printf %x 15664 #3d30 然后再使用jstack查询线程的堆栈信息 语法:jstack <pid> | grep -a 线程id(十六进制) jstack <pid> | grep -a 3d30 这样就找出了有问题的代码了

Win10 WMI Provider Host进程占用CPU过高的解决方法

在使用系统过程中,偶尔会出现由于某些进程而导致CPU等硬件资源占用过多,进而出现系统卡顿的情况.一个Win10用户发现“WMI Provider Host“占用了过多CPU资源导致系统卡顿,该如何解决这个问题呢? 解决方法: 可以尝试关闭Windows防火墙服务来解决这个问题. 1.按住win+R,输入services.msc,回车. 2.在服务里面找到Windows Firewall,双击,在启动类型中选择“禁止”. 3.重启Win10系统,然后测试问题是否得到解决. 有的用户不知道是哪个进程

Linux 线程占用CPU过高定位分析

今天朋友问我一个Linux程序CPU占用涨停了,该如何分析, CPU占用过高,模拟CPU占用过高的情况 先上一段代码: 1 #include <iostream> 2 #include <thread> 3 #include <vector> 4 5 6 int main(int argc, char **argv) { 7 8 std::vector<std::thread> test_threads; 9 for(int i = 0; i < 9;

Linux排查Java程序占用CPU很高的解决办法

Java的工具集相当强大,学习成本也很低,处理线上问题时,jstack这个工具就比微软的windbg,好学好用很多,3步找出占用CPU很高的源所在.而windbg反人类的各种命令,实在不敢恭维. 故意设置了一个CPU占用很高的场景: 排查问题,步骤: 1. ps -mp [替换为进程ID PID] -o THREAD,tid,time 发现线程6322.6323占用CPU很高,时间也很长. 2. printf “%x” [线程ID TID] 把TID转换为16进制. 3. jstack [进程I

Linux排查java程序占用cpu过高的线程代码

分几步骤: 1.通过top,查出占用CPU过高的java进程 ,比如: pid :6666 2.通过ps -mp 6666 -o THREAD,tid,time| sort -n -k1 -r 查看此进程占用线程的情况,比如查到占用CPU异常高的线程的线程Id :8888 以上两步,可以直接通过top -H搞定 3.将需要的线程ID转换为16进制格式: printf “%x\n” 8888 [[email protected]]# printf “%x\n” 8888“22b8n” 4.最后打印