Menu

JVM内部存款和储蓄器分析,扫地僧都会的有关JVM深入分析那么些事儿



利用IBM Thread and Monitor Dump Analyzer分析dumap文件

IBM Thread and Monitor Dump Analyzer 下载地址

java -jar jca463.jar

启动IBM Thread and Monitor Dump Analyzer

图片 1图片.jpg

启动后,通过菜单File->Open打开生成的dump文件jstack.log

图片 2图片.jpg

在IBM Thread and Monitor Dump Analyzer for
Java工具中,请求线程可分为以下几种状态: 1.死锁,Deadlock
2.执行中,Runnable 3.等待资源,Waiting on condition
4.等待监控器检查资源,Waiting on monitor 5.暂停,Suspended
6.对象等待中,Object.wait() 7.阻塞,Blocked 8.停止,Parked
Deadlock:死锁线程:一般指多个线程调用间,进入相互资源占用,导致一直等待无法释放的情况。
Runnable:一般指该线程正在执行状态中,该线程占用了资源,正在处理某个请求,有可能正在传递SQL到数据库执行,有可能在对某个文件操作,有可能进行数据类型等转换。
Waiting on
condition:等待资源,如果堆栈信息明确是应用代码,则证明该线程正在等待资源,一般是大量读取某资源,且该资源采用了资源锁的情况下,线程进入等待状态,等待资源的读取。又或者,正在等待其他线程的执行等。

Blocked:线程阻塞,是指当前线程执行过程中,所需要的资源长时间等待却一直未能获取到

jps

jps命令可以显示当前运行java进程以及相关参数。

man jps  //可以命令行jps的用法说明

jps -q //只显示pid,不显示class名称,jar文件名和传递给main 方法的参数

jps -m //输出传递给main 方法的参数

jps -l //输出应用程序main class的完整package名 或者 应用程序的jar文件完整路径名

jps -v 输出传递给JVM的参数

获取JVM的dump文件

大致涉及如下内容:

IBM HeapAnalyzer分析内存

IBM HeapAnalyzer 下载地址

java -jar ha456.jar

启动HeapAnalyzer

图片 3图片.jpg

HeapAnalyzer启动后,通过菜单File->Open打开生成的dump文件jvmDump。

图片 4图片.jpg

通过dump信息分析内存泄漏的对象。主要思路是堆内存占用比例,比例越大说明堆内存消耗越多,最后需要在程序中找到使用该对象的地方,再分析程序,确定产生内存泄漏的原因。

实战

下面以一个简单的例子,分析出运行项目中最消耗cpu的线程并定位代码。

  • 得到进程id
    jps or ps,以ps为例:

ps -ef | grep Kernel | grep -v grep

得到进程id 即pid
然后查找该进程id下各个线程中最消耗的那个线程tid,用top指令:

top -Hp <pid>

得到线程id
即tid,由于jstack中tid和nid都是十六进制的,因此需要将得到的tid转换为十六进制:

printf '%x\n' <tid>

将得到的十六进制tid,用jstack即可定位具体线程:

jstack <pid> | grep <tid十六进制>

  1. 老子《道德经》第三章,老子故里,中国鹿邑。

利用jstack获取JVM的线程dump文件

jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。
线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。
如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java
stack和native
stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。另外,jstack工具还可以附属到正在运行的java程序中,看到当时运行的java程序的java
stack和native stack的信息,
如果现在运行的java程序呈现hung的状态,jstack是非常有用的。

#173824是jvm进程号jstack 173824 | tee -a jstack.log

jstat

jstat(JVM Statistics Monitoring
Tool)是用于监控虚拟机各种运行状态信息的命令行工具。他可以显示本地或远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。

jstat [options] <pdi>

[options]:

–class 监视类装载、卸载数量、总空间及类装载所耗费的时间 
–gc 监视Java堆状况,包括Eden区、2个Survivor区、老年代、永久代等的容量 
–gccapacity 监视内容与-gc基本相同,但输出主要关注Java堆各个区域使用到的最大和最小空间 
–gcutil 监视内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比 
–gccause 与-gcutil功能一样,但是会额外输出导致上一次GC产生的原因 –gcnew 监视新生代GC的状况 
–gcnewcapacity 监视内容与-gcnew基本相同,输出主要关注使用到的最大和最小空间 
–gcold 监视老年代GC的状况 
–gcoldcapacity 监视内容与——gcold基本相同,输出主要关注使用到的最大和最小空间 
–gcpermcapacity 输出永久代使用到的最大和最小空间 
–compiler 输出JIT编译器编译过的方法、耗时等信息
–printcompilation 输出已经被JIT编译的方法

jstat -class <pid> 显示加载class的数量,及所占空间等信息。

结果说明:
Loaded 装载的类的数量 
Bytes 装载类所占用的字节数 
Unloaded 卸载类的数量 
Bytes 卸载类的字节数 
Time 装载和卸载类所花费的时间

jstat -gc <pid>: 可以显示gc的信息,查看gc的次数,及时间。

结果说明:
S0C 年轻代中第一个survivor(幸存区)的容量 (字节) 
S1C 年轻代中第二个survivor(幸存区)的容量 (字节) 
S0U 年轻代中第一个survivor(幸存区)目前已使用空间 (字节) 
S1U 年轻代中第二个survivor(幸存区)目前已使用空间 (字节) 
EC 年轻代中Eden(伊甸园)的容量 (字节) 
EU 年轻代中Eden(伊甸园)目前已使用空间 (字节) 
OC Old代的容量 (字节) 
OU Old代目前已使用空间 (字节) 
PC Perm(持久代)的容量 (字节) 
PU Perm(持久代)目前已使用空间 (字节) 
YGC 从应用程序启动到采样时年轻代中gc次数 
YGCT 从应用程序启动到采样时年轻代中gc所用时间(s) 
FGC 从应用程序启动到采样时old代(全gc)gc次数 
FGCT 从应用程序启动到采样时old代(全gc)gc所用时间(s) 
GCT 从应用程序启动到采样时gc用的总时间(s)
2、发现程序异常前通过执行指令,直接生成当前JVM的dump文件,127465是指JVM的进程号
jmap -dump:format=b,file=jvmDump 127465

注:第一种方式是当前JVM出现问题后才能生成dmp文件,实时性不高,第二种方式在执行时,JVM是暂停服务的,所以对线上的运行会产生影响。所以建议第一种方式

jmap

jmap是JDK自带的工具软件,主要用于打印指定Java进程(或核心文件、远程调试服务器)的共享对象内存映射或堆内存细节。堆Dump是反应Java堆使用情况的内存镜像,其中主要包括系统信息、虚拟机属性、完整的线程Dump、所有类和对象的状态等。
常见内存错误:

OutOfMemoryError 年老代内存不足。
OutOfMemoryError:PermGen Space 永久代内存不足。
OutOfMemoryError:GC overhead limit exceed 垃圾回收时间占用系统运行时间的98%或以上。

jmap [optioins] <pid>

[options]

<no option> 如果使用不带选项参数的jmap打印共享对象映射,将会打印目标虚拟机中加载的每个共享对象的起始地址、映射大小以及共享对象文件的路径全称。这与Solaris的pmap工具比较相似。
-dump:[live,]format=b,file=<filename> 以hprof二进制格式转储Java堆到指定filename的文件中。live子选项是可选的。如果指定了live子选项,堆中只有活动的对象会被转储。想要浏览heap dump,你可以使用jhat(Java堆分析工具)读取生成的文件。
-finalizerinfo 打印等待终结的对象信息。
-heap 打印一个堆的摘要信息,包括使用的GC算法、堆配置信息和generation wise heap usage。
-histo[:live] 打印堆的柱状图。其中包括每个Java类、对象数量、内存大小(单位:字节)、完全限定的类名。打印的虚拟机内部的类名称将会带有一个’*’前缀。如果指定了live子选项,则只计算活动的对象。
-permstat 打印Java堆内存的永久保存区域的类加载器的智能统计信息。对于每个类加载器而言,它的名称、活跃度、地址、父类加载器、它所加载的类的数量和大小都会被打印。此外,包含的字符串数量和大小也会被打印。
-F 强制模式。如果指定的pid没有响应,请使用jmap -dump或jmap -histo选项。此模式下,不支持live子选项。
-h 打印帮助信息。
-help 打印帮助信息。
-J<flag> 指定传递给运行jmap的JVM的参数。
1、JVM启动时增加两个参数:
 #出现 OOME 时生成堆 dump: -XX:+HeapDumpOnOutOfMemoryError #生成堆文件地址: -XX:HeapDumpPath=/opt/logs/jvm/

Tomcat配置自动生产dump文件参考Tomcat性能调优

jstack

jstack是虚拟机堆栈追踪工具,用于生成虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。
线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java
stack和native
stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。另外,jstack工具还可以附属到正在运行的java程序中,看到当时运行的java程序的java
stack和native stack的信息,
如果现在运行的java程序呈现hung的状态,jstack是非常有用的。

线程状态:

NEW 未启动的
RUNNABLE 在虚拟中运行的
BLOCKED 受阻塞并等待监视器锁
WAITTING 无限期等待另一个线程执行特定操作
TIMED_WAITTING 有限期的等待另一线程执行特定操作
TERMINATED 已退出的

jstack [options] <pid> //pid可以通过jps或者top获取,后面给出的具体分析实例会写到

[options]:

jstack -F 当’jstack [-l] pid’没有相应的时候强制打印栈信息

jstack -l 长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表.

jstack -m 打印java和native c/c++框架的所有栈信息.

jstack -h 打印帮助信息
  • jps
  • jstack
  • jstat
  • jmap
  • 实战

JVM为我们提供了很多工具,我们可以用它来监测运行中的程序,对于程序优化和问题分析很有帮助,今天就聊聊这方面的操作。

“不尚贤,使民不争;不贵难得之货,使民不为盗;不见可欲,使民心不乱。
是以圣人之治,虚其心,实其腹,弱其志,强其骨,常使民无知无欲。
使夫知者不敢为也。
为无为,则无不治。”[\[1\]](https://www.jianshu.com/p/df19eac22229#fn1)

标签:,

发表评论

电子邮件地址不会被公开。 必填项已用*标注

相关文章

网站地图xml地图