http://heylinux.com/archives/1085.html通过 thread dump 分析找到高CPU耗用与内存溢出的Java代码

首先,要感谢我的好朋友 钊花 的经验分享。

相信大家在实际的工作当中,肯定会遇到由代码所导致的高CPU耗用以及内存溢出的情况。
通常这种情况发生时,我们会认为这些问题理所当然的该由开发人员自己去解决,因为操作系统环境是没有任何问题的。

但实际上,我们是可以帮助他们的,效果好的话还可以定位到具体出问题的代码行数,思路如下:
1.通过对CPU与内存的耗用情况判断是否存在问题;
2.通过top命令找到可疑的线程的ID;
3.确认应用服务器的console信息的输出位置;
4.通过kill -3 ID 的方式获取thread dump信息;
5.备份console日志,并通过线程ID检查与代码相关的信息。

下面,我们开始具体的操作过程:

1.通过对CPU与内存的耗用情况判断是否存在问题;
判断CPU可以直接在top中查看CPU的 %us 数值就可以了,通常在50%以下都算正常,一旦超过60%甚至高到80-90且稳居不下,那么就肯定存在问题了;
判断内存时需要注意的是,直接看第一行Mem:的used数值是不准确的,因为通常在运行一段时间后,这个值都会非常大,这是因为Linux对内存的使用理念“内存就是拿来用的”,它会将空闲的内存尽可能的用于缓存,来提升性能,所以我们应该更多的参考 -/+ buffers/cache: 这一行的used数值,如果该值与第一行的used数值很接近且与内存总量相差很少的话,那么内存才算处于紧张的状态;
虚拟内存的耗用也值得参考,Linux只有在内存确实不够用的情况下才会大量使用虚拟内存,如果虚拟内存使用值为0或者100兆左右,那么可以确定物理内存尚且充足;
系统负载的数值也很值得参考,即top中的 load average,通常小于 1 代表非常良好,1-5之间代表正常,大于5 则表明系统处于负载的状态,超出的数值越大负载越大。

2.通过top命令找到可疑的线程的ID;
执行top命令,在这个Linux的“任务管理器”中输入大写的“H”来打开线程模式,然后所有线程会默认以CPU耗用高低排序;
如果想以内存进行排序,再敲入大写的“M”即可,其中“RES”看到的就是物理内存的耗用大小,但由于线程的共享内存原理,我们看到的每个线程的内存大小都和他们所属进程是一样的。

3.确认应用服务器的console信息的输出位置;
通常来说,应用服务器的console信息都会输出到log当中,比如Tomcat会输出到catalina.out文件中。
但jboss与weblogic就需要进行一些修改设置才行,其中:
jboss如果使用了官方的启动脚本,则需要修改启动脚本中的如下两行中的 /dev/null,将其改为指定的log文件位置,如 /opt/jboss_console.log,再重启jboss即可。
---------------------------------------------------------------------
JBOSS_CONSOLE="/dev/null"

JBOSS_CONSOLE=${JBOSS_CONSOLE:-"/dev/null"}
---------------------------------------------------------------------

weblogic则需要在console管理界面中的“域结构”-“环境”-“区域”-“服务器”-“AdminServer”-“日志记录”-“高级”- 勾选“已启动重定向标准输出日志记录”,再点击“激活更改”并重启weblogic即可。然后所有的console信息都会输出到logs目录下的AdminServer.log文件中。

4.通过kill -3 ID 的方式获取thread dump信息;
确认了应用服务器的console信息输出,并找到可疑的线程ID之后,执行 kill -3 ID 即可将该线程这一刻的所有thread dump信息输出到log当中。
建议多执行几次该命令,以便获取充足的信息。

5.备份console日志,并通过线程ID检查与代码相关的信息。
执行了thread dump信息输出之后,立刻使用cp命令备份log文件;
将log文件下载到本地,将进程ID换算成为十六进制,比如 29433 换算为十六进制就是 72f9;
打开log文件(建议使用UE或Notepad++等编辑器),搜索包含 72f9 的相关信息,然后仔细检查相关代码。

以我的实际情况为例:
下面这一段信息就包含了“nid=0x72f9”,表明与进程29433相关,所提到的 JIoEndpoint.java 则是实际的代码文件,后面的 442 则代表具体的行数。
---------------------------------------------------------------------
"http-0.0.0.0-80-78" daemon prio=10 tid=0x00000000686db800 nid=0x72f9 in Object.wait() [0x000000004cea6000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00002aab0bccd5b8> (a org.apache.tomcat.util.net.JIoEndpoint$Worker)
at java.lang.Object.wait(Object.java:485)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.await(JIoEndpoint.java:416)
- locked <0x00002aab0bccd5b8> (a org.apache.tomcat.util.net.JIoEndpoint$Worker)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:442)
at java.lang.Thread.run(Thread.java:619)
---------------------------------------------------------------------

到此,实际的工作才刚刚开始,需要开发人员仔细检查所有类似的信息,然后找出有问题的代码。

有资料说,thread dump 的作用其实还有很多,可以从中发现很多应用程序的运行问题,比如死锁等;且有一个Eclipse插件的可视化分析工具“lockness” 可以对该类日志进行更专业的分析。
 
 
 
关于这个话题文章链接

通过 thread dump 分析找到高CPU耗用与内存溢出的Java代码的更多相关文章

  1. 性能分析之-- JAVA Thread Dump 分析综述

    性能分析之-- JAVA Thread Dump 分析综述       一.Thread Dump介绍 1.1什么是Thread Dump? Thread Dump是非常有用的诊断Java应用问题的工 ...

  2. tomcat thread dump 分析【转载】

    前言 Java Thread Dump 是一个非常有用的应用诊断工具, 通过thread dump出来的信息, 可以定位到你需要了解的线程, 以及这个线程的调用栈. 如果配合linux的top命令, ...

  3. 性能分析之– JAVA Thread Dump 分析

    最近在做性能测试,需要对线程堆栈进行分析,在网上收集了一些资料,学习完后,将相关知识整理在一起,输出文章如下. 一.Thread Dump介绍 1.1什么是Thread Dump? Thread Du ...

  4. (转)性能分析之-- JAVA Thread Dump 分析综述

    原文链接:http://blog.csdn.net/rachel_luo/article/details/8920596 最近在做性能测试,需要对线程堆栈进行分析,在网上收集了一些资料,学习完后,将相 ...

  5. Java_tomcat thread dump 分析

    前言 Java Thread Dump 是一个非常有用的应用诊断工具, 通过thread dump出来的信息, 可以定位到你需要了解的线程, 以及这个线程的调用栈. 如果配合linux的top命令, ...

  6. tomcat thread dump 分析

    前言 Java Thread Dump 是一个非常有用的应用诊断工具, 通过thread dump出来的信息, 可以定位到你需要了解的线程, 以及这个线程的调用栈. 如果配合linux的top命令, ...

  7. java jvm heap dump及 thread dump分析

    一.概念: 在进行java应用故障分析时,经常需要分析内存和cpu信息,也就说所谓的heap dump 和 thread dump heap dump: heap dump文件是一个二进制文件,需要工 ...

  8. java之Thread Dump分析

    什么是Thread Dump Thread Dump是非常有用的诊断Java应用问题的工具.每一个Java虚拟机都有及时生成所有线程在某一点状态的thread-dump的能力,虽然各个 Java虚拟机 ...

  9. Java常见问题分析(内存溢出、内存泄露、线程阻塞等)

    Java垃圾回收机制(GC) 1.1 GC机制作用 1.2 堆内存3代分布(年轻代.老年代.持久代) 1.3 GC分类 1.4 GC过程 Java应用内存问题分析 2.1 Java内存划分 2.2 J ...

随机推荐

  1. 【概率论】hdu5985 Lucky Coins

    kill(i,j)表示第i种硬币在第j轮或者之前就死光的概率,它等于(1-pi^j)^num(i) rev(i,j)表示第i种硬币在j轮后仍然存活的概率,它等于1-kill(i,j) 然后对每种硬币i ...

  2. JVM命令-java服务器故障排查

    一.top(Linux命令) 执行top命令:    (查看进程15477的详细情况,下文用到) 系统信息(前五行): 第1行:Top 任务队列信息(系统运行状态及平均负载),与uptime命令结果相 ...

  3. Problem G: 十进制数转换为二进制数

    #include<stdio.h> int main() { ]; while(scanf("%d",&n)!=EOF) { ; ) { a[i++]=n%; ...

  4. bzoj 3384: [Usaco2004 Nov]Apple Catching 接苹果

    双倍经验题... -->1750 dp!! 3384: [Usaco2004 Nov]Apple Catching 接苹果 Time Limit: 1 Sec  Memory Limit: 12 ...

  5. win7与Ubuntu 13.04双系统修改启动项顺序

    在在win7下安装了Ubuntu 13.04后,在grub中,win7启动想是最后一个,为了把win7设置为默认启动项,需要更改grub设置.google了半天,发现更改/etc /default/g ...

  6. JavaScript基础入门教程(一)

    本系列教程的说明 本教程说白了可以说是我自己学习JavaScript的笔记,主要内容参考自<JavaScript权威指南>,部分内容可能来自互联网,本系列教程假设学者之前学过c或者其它的编 ...

  7. 支持向量机(SVM)介绍

    一.了解支持向量机   支持向量机(support vector machings, SVM) 是一种二分类模型,其基本模型定义为特征空间上的间隔最大的线性分类器,其学习策略便是间隔最大化,最终可转化 ...

  8. 利用Nodejs & Cheerio & Request抓取Lofter美女图片

    还是参考了这篇文章: http://cnodejs.org/topic/54bdaac4514ea9146862abee 另外有上面文章 nodejs抓取网易公开课的一些经验. 代码如下,注意其中用到 ...

  9. ElementUI使用问题记录:设置路由+iconfont图标+自定义表单验证

    一.关于导航怎么设置路由 1.在el-menu这个标签的属性中添加 router ,官方文档的解释是:启用vue-router 这种模式 2.在el-menu-item标签中的index属性直接书写路 ...

  10. springMVC配置静态资源访问的<mvc:resources>标签的使用

    在springmvc中,为了引用资源的访问不会类似Controller一样被拦截,区分出关注的资源的访问,一般我们在springMVC里面的拦截都会配置为"/",拦截所有的.但是这 ...