Java应用程序高CPU故障诊断(troubleshooting)思路

系统运行出现高CPU报警,一般可以通过top或者任务管理器找到哪些进程在使用CPU,但这个粒度不能让我们知道得更多,我们需要找到程序的哪部分在占用CPU并且在占用CPU做什么,这样才有利于我们以后调优,下面介绍一种可行的思路:

  1. 找到占用CPU高的进程p
  2. 找到进程p中占用CPU高的线程t
  3. 找到线程t在做什么

本文以Linux下Java应用程序为例,其他环境或程序可参照该思路,只要思路清晰就好办了

  • 打开top,在top中按shift+p按照CPU使用量倒序显示进程,找到占用CPU较高的进程号pid,然后退出top
  • top -H -p pid 显示该进程中线程的运行情况,pid可以指定多个,在top中按shift+p按照CPU占用倒序显示线程,找到占用CPU高的线程tid,比如是27890,通过printf打印出该tid的是十六进制号
 $ printf "%x\n" 27890
 6cf2
  • 通过threaddump工具以十六进制号查看该线程当前的堆栈信息,Java中threaddump工具为jstack
$ jstack -l <pid> | grep -i 0x6cf2 -A 15
  • 多次重复执行1-3步骤,确定线程所做的耗时操作,注意步骤1-3之间延时越短越准确,最好在多个shell窗口下执行

通过上面的操作我们就可以确定哪段代码在大量占用CPU资源了,得到的结果如下

"Thread-12" daemon prio=10 tid=0x00007f926c021000 nid=0xba7 runnable [0x00007f92c06d7000]
   java.lang.Thread.State: RUNNABLE
        at java.io.FileOutputStream.writeBytes(Native Method)
        at java.io.FileOutputStream.write(FileOutputStream.java:282)
        at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
        at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)
        - locked <0x0000000780d79ae0> (a java.io.BufferedOutputStream)
        at java.io.PrintStream.write(PrintStream.java:432)
        - locked <0x0000000780d79ac0> (a java.io.PrintStream)
        at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)
        at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272)
        at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:85)
        - locked <0x0000000780d79c10> (a java.io.OutputStreamWriter)
        at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:168)
        at java.io.PrintStream.write(PrintStream.java:477)
        - locked <0x0000000780d79ac0> (a java.io.PrintStream)
        at java.io.PrintStream.print(PrintStream.java:619)
        at java.io.PrintStream.println(PrintStream.java:773)
        - locked <0x0000000780d79ac0> (a java.io.PrintStream)
        at org.apache.tomcat.util.log.SystemLogHandler.println(SystemLogHandler.java:242)
        at java.lang.Throwable.printStackTrace(Throwable.java:461)
        - locked <0x0000000780d79a98> (a org.apache.tomcat.util.log.SystemLogHandler)
        at java.lang.Throwable.printStackTrace(Throwable.java:451)
        at com.zhaopin.framework.cache.CacheListHandler$TimeoutTimerThread.run(CacheListHandler.java:101)
        at java.lang.Thread.run(Thread.java:662)

上述仅是一个故障诊断的思路,非Java或者Linux可以通过类似的工具完成,比如windows下可以通过Process Explorer替代top查看进程和线程相关内容等

时间: 2024-08-07 08:34:14

Java应用程序高CPU故障诊断(troubleshooting)思路的相关文章

JAVA应用程序占用CPU、内存过高分析过程

1.查看cpu占有率 top -P 2.查看进程cpu占用率 ps -mp 3749 -o THREAD,tid,time|sort -rn|head -n 20 3.查看java堆栈信息 su - nobody -c "/usr/java/jdk1.6.0_21/bin/jstack 3749|grep 34d8 -A 30" 注意:这里要使用程序启动的用户执行此命令 使用root会提示: Unable to open socket file: target process not

记一次服务器高CPU的排查思路

现象 排查思路 另一台服务器CPU正常,由于消息中心有部分老接口是域名调用的,网关已做负载均衡,并且pinpoint上的两台服务器gc如图,初步猜测是否是负载不均衡导致. 经运维调试nginx权重无效,证明与负载均衡无关.那么先看子线程,这种情况必定由某几个线程引起 ps -mp pid -o THREAD,tid,time命令查看子线程,如图 这个数据上,分两部分看,1.有3个占用高的线程,2.执行时间可以注意到分别是4天,1天,23小时.说明线程出于某种情况,死锁,死循环. 由于这时候jst

[Java] HashMap 导致的高 CPU 使用率

今天在生产环境遇到一个问题,Java 应用程序的 cpu 使用比例很高,导致整台机器的 cpu 使用率高达 90% ,正常情况下是 20% 左右. 把 Thread dump 导出来,利用 IBM Thread Analyzer for Java 工具进行分析.总共有60 多个在线线程,其中有 15 个线程都在执行同一个文件中的同一句代码,最顶层的调用是 HashMap.get() . HashMap 的底层数据结构是数组 + 链表进行存储,链表用于处理 hash 碰撞的情况.正常情况下链接是线

通过 thread dump 分析找到高CPU耗用与内存溢出的Java代码

http://heylinux.com/archives/1085.html通过 thread dump 分析找到高CPU耗用与内存溢出的Java代码 首先,要感谢我的好朋友 钊花 的经验分享. 相信大家在实际的工作当中,肯定会遇到由代码所导致的高CPU耗用以及内存溢出的情况. 通常这种情况发生时,我们会认为这些问题理所当然的该由开发人员自己去解决,因为操作系统环境是没有任何问题的. 但实际上,我们是可以帮助他们的,效果好的话还可以定位到具体出问题的代码行数,思路如下: 1.通过对CPU与内存的

java SE程序关于高并发的注意事项

最近做一个java SE程序.使用线程池进行高并发任务的处理.其中任务处理过程中会有查询数据库操作,导致任务处理非常迟缓.于是在网上查找资料.最终解决现在把有关的注意事项进行总结.一.关于线程池的注意事项.对于多个任务,线程池最好不要公用.应该把线程池分开关于线程池的代码 </pre><pre code_snippet_id="547077" snippet_file_name="blog_20141209_1_7940215" name=&quo

生产环境下JAVA进程高CPU占用故障排查

问题描述:生产环境下的某台tomcat7服务器,在刚发布时的时候一切都很正常,在运行一段时间后就出现CPU占用很高的问题,基本上是负载一天比一天高. 问题分析:1,程序属于CPU密集型,和开发沟通过,排除此类情况.2,程序代码有问题,出现死循环,可能性极大. 问题解决:1,开发那边无法排查代码某个模块有问题,从日志上也无法分析得出.2,记得原来通过strace跟踪的方法解决了一台PHP服务器CPU占用高的问题,但是通过这种方法无效,经过google搜索,发现可以通过下面的方法进行解决,那就尝试下

Java多线程与高并发:高并发解决思路

Java多线程与高并发:高并发解决思路 小玲子之凌空蹈虚关注 122018.11.21 09:55:30字数 1,553阅读 4,228 來源:http://www.wangtianyi.top/blog/2018/05/11/javaduo-xian-cheng-yu-gao-bing-fa-liu-gao-bing-fa-jie-jue-si-lu/ 缓存并发 image.png 当大量请求访问同一个没有被缓存的数据的时候,会发送大量请求给数据库,导致数据库压力过大,还会导致一致性问题,所以

java 程序消耗 cpu 100% 查找方法

问题原因:由于HashMap是非线程安全的,在多线程访问时,造成死循环. 查找问题方法: 1. Java代码   top 找出最耗费cpu的进程号 如:27377 2. Java代码   top -p 27377 -H 找出此进程下的所有线程,然后找出最耗cpu线程号 如:27433 3. Java代码   python  hex(27433) 将十进制数转为16进制 如:0x6b29 4. Java代码   jstack 27377 >cpu.log 将此进程号的Java堆栈信息打印到文件中

【转】成为Java顶尖程序员 ,看这11本书就够了

成为Java顶尖程序员 ,看这11本书就够了 转自:http://developer.51cto.com/art/201512/503095.htm 以下是我推荐给Java开发者们的一些值得一看的好书.但是这些书里面并没有Java基础.Java教程之类的书,不是我不推荐,而是离我自己学习 Java基础技术也过去好几年了,我学习的时候看的什么也忘了,所以我不能不负责任地推荐一些我自己都没有看过的书给大家. 作者:来源:攻城狮之家|2015-12-31 09:55 收藏 分享 “学习的最好途径就是看