Java内存泄漏分析系列之一:利用jstack定位线程堆栈信息
发布时间:2023-03-28 11:09:06 所属栏目:教程 来源:
导读:前一段时间上线的系统升级之后,出现了严重的高cpu的问题,于是开始了一系列的优化处理之中,现在将这个过程做成一个系列的文章。
基本概念
在对Java内存泄漏进行分析的时候,需要对jvm运行期间的内存占用、线
基本概念
在对Java内存泄漏进行分析的时候,需要对jvm运行期间的内存占用、线
|
前一段时间上线的系统升级之后,出现了严重的高cpu的问题,于是开始了一系列的优化处理之中,现在将这个过程做成一个系列的文章。 基本概念 在对Java内存泄漏进行分析的时候,需要对jvm运行期间的内存占用、线程执行等情况进行记录的dump文件,常用的主要有thread dump和heap dump。 thread dump 主要记录JVM在某一时刻各个线程执行的情况,以栈的形式显示,是一个文本文件。通过对thread dump文件可以分析出程序的问题出现在什么地方,从而定位具体的代码然后进行修正。thread dump需要结合占用系统资源的线程id进行分析才有意义。 heap dump 主要记录了在某一时刻JVM堆中对象使用的情况,即某个时刻JVM堆的快照,是一个二进制文件,主要用于分析哪些对象占用了太对的堆空间,从而发现导致内存泄漏的对象。 上面两种dump文件都具有实时性,因此需要在服务器出现问题的时候生成,并且多生成几个文件,方便进行对比分析。下面我们先来说一下如何生成 thread dump。 top后面的参数-c可以显示进程详细的信息。top命令执行的时候还可以执行一些快捷键: 1 对于多核服务器,可以显示各个cpu占用资源的情况 shift+h 显示所有的线程信息 shift+w 将当前 top 命令的设置保存到 ~/.toprc 文件中,这样不用每次都执行快捷键了 接下来我们清楚今天的主角 jstack,这是一个在JDK5开始提供的内置工具,可以打印指定进程中线程运行的状态,包括线程数量、是否存在死锁、资源竞争情况和线程的状态等等。有下面的几个常用的参数: 上面命令中 -A 10 参数用来指定显示行数,否则只会显示一行信息。 这样通过上图,可以很快地定位到程序问题的代码,然后对代码进行分析和改进即可。注意:需要在多个时间段提出多个 Thread Dump信息,然后综合进行对比分析,单独分析一个文件是没有意义的。 #!/bin/bash if [ $# -ne 1 ]; then echo "usage: $0 <pid> [line-number]" exit 1 # java home if test -z $JAVA_HOME then JAVA_HOME='/usr/local/jdk' #pid pid=$1 # checking pid if test -z "$($JAVA_HOME/bin/jps -l | cut -d '' -f 1 | grep $pid)" then echo "process of $pid is not exists" exit #line number if test -z $linenum then linenum=10 stackfile=stack$pid.dump threadsfile=threads$pid.dump # generate java stack $JAVA_HOME/bin/jstack -l $pid >> $stackfile ps -mp $pid -o THREAD,time | sort -k2r | awk '{if ($1 !="USER" && $2 != "0.0" && $8 !="-") print $8;}' | xargs printf "%x\n" >> $threadsfile tids="$(cat $threadsfile)" for tid in $tids do echo "------------------------------ ThreadId ($tid) ------------------------------" cat $stackfile | grep 0x$tid -A $linenum done rm -f $stackfile $threadsfile (编辑:汽车网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐
