Linux - java 分析(jps、Jstat 、jstack\pstack、jmap、jhat)

1、jps(Java Virtual Machine Process Status Tool)   

jps主要用来输出JVM中运行的进程状态信息。语法格式如下:

jps [options] [hostid]

如果不指定hostid就默认为当前主机或服务器。

命令行参数选项说明如下:

-q 不输出类名、Jar名和传入main方法的参数

-m 输出传入main方法的参数

-l 输出main类或Jar的全限名

-v 输出传入JVM的参数   

例如:jps -ml

Linux - java 分析(jps、Jstat 、jstack\pstack、jmap、jhat)

 

再sudo -u hive /usr/java/latest/bin/jstack 19661(此为进程号) > /tmp/jstack.txt

 

2、Jstat (JVM统计监测工具)

语法格式如下:

jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]

例如:jstat -gcutil pid 5s(每隔5s监控一次内存回收情况)

Linux - java 分析(jps、Jstat 、jstack\pstack、jmap、jhat)

 

E 代表 Eden 区使用率;

O(Old)代表老年代使用率    ;

P(Permanent)代表永久代使用率;

CCS 压缩使用比例

M 元空间(MetaspaceSize)已使用的占当前容量百分比

YGC(Young GC)代表Minor GC 次数;

YGCT代表Minor GC耗时;

FGC(Full GC)代表Full GC次数;

FGCT(Full GC)代表Full GC耗时;

GCT代表Minor & Full GC共计耗时。

3、jstack -F pid 检查是否有死锁

jstack主要用来查看某个Java进程内的线程堆栈信息。语法格式如下:

jstack [option] pid

jstack [option] executable core

jstack [option] [[email protected]]remote-hostname-or-ip

    命令行参数选项说明如下:

-l long listings,会打印出额外的锁信息,在发生死锁时可以用jstack -l pid来观察锁持有情况

-m mixed mode,不仅会输出Java堆栈信息,还会输出C/C++堆栈信息(比如Native方法)

    jstack可以定位到线程堆栈,根据堆栈信息我们可以定位到具体代码,所以它在JVM性能调优中使用得非常多。下面我们来一个实例找出某个Java进程中最耗费CPU的Java线程并定位堆栈信息,用到的命令有ps、top、printf、jstack、grep。

(一):top 查看目前系统中cpu占用最高的进程是什么

Linux - java 分析(jps、Jstat 、jstack\pstack、jmap、jhat)

(二):top -H -p pid (查看改进程中那个线程的cpu占用率最高)

Linux - java 分析(jps、Jstat 、jstack\pstack、jmap、jhat)

 

(三) :printf "%x\n" 4922

Linux - java 分析(jps、Jstat 、jstack\pstack、jmap、jhat)

 

  • jstack -2617 | grep 133a

发现打印不出来任何结果

  • pstack 进程号
  • Linux - java 分析(jps、Jstat 、jstack\pstack、jmap、jhat)
  • 发现是引入的第三方so包导致。

 

(:pstack是一个shell脚本,用于打印正在运行的进程的栈跟踪信息,它实际上是gstack的一个链接,而gstack本身是基于gdb封装的shell脚本.。此命令可显示每个进程的栈跟踪。pstack 命令必须由相应进程的属主或 root 运行。可以使用 pstack 来确定进程挂起的位置。此命令允许使用的唯一选项是要检查的进程的 PID。

与jstack功相比, 它能对潜在的死锁予以提示, 而pstack只提供了线索, 需要gdb进一步的确定。

pstack是gdb的一部分,如果系统没有pstack命令,使用yum搜索安装gdb即可。

这个命令在排查进程问题时非常有用,比如我们发现一个服务一直处于work状态(如假死状态,好似死循环),使用这个命令就能轻松定位问题所在;可以在一段时间内,多执行几次pstack,若发现代码栈总是停在同一个位置,那个位置就需要重点关注,很可能就是出问题的地方)

4、jmap(Memory Map)和jhat(Java Heap Analysis Tool)

jmap用来查看堆内存使用状况,一般结合jhat使用。

jmap语法格式如下:

jmap [option] pid

jmap [option] executable core

jmap [option] [[email protected]]remote-hostname-or-ip

如果运行在64位JVM上,可能需要指定-J-d64命令选项参数。

jmap -permstat pid

使用jmap -heap pid查看进程堆内存使用情况,包括使用的GC算法、堆配置参数和各代中堆内存使用情况。

Linux - java 分析(jps、Jstat 、jstack\pstack、jmap、jhat)

 

 使用jmap -histo[:live] pid查看堆内存中的对象数目、大小统计直方图,如果带上live则只统计活对象

Linux - java 分析(jps、Jstat 、jstack\pstack、jmap、jhat)

 

class name是对象类型,说明如下:

B  byte

C  char

D  double

F  float

I  int

J  long

Z  boolean

[  数组,如[I表示int[]

[L+类名 其他对象

还有一个很常用的情况是:用jmap把进程内存使用情况dump到文件中,再用jhat分析查看。jmap进行dump命令格式如下:

jmap -dump:format=b,file=/opt/logs/dump.dat 2617

Linux - java 分析(jps、Jstat 、jstack\pstack、jmap、jhat)

 

dump出来的文件可以用MAT、VisualVM等工具查看,这里用jhat查看:

jhat -port 2617 /opt/logs/dump.dat

Linux - java 分析(jps、Jstat 、jstack\pstack、jmap、jhat)

 

打开网页

http://192.168.2.110:2617/

Linux - java 分析(jps、Jstat 、jstack\pstack、jmap、jhat)

 

  1. jstack信息分析

各状态说明:

New: 当线程对象创建时存在的状态,此时线程不可能执行;

Runnable:当调用thread.start()后,线程变成为Runnable状态。只要得到CPU,就可以执行;

Running:线程正在执行;

Waiting:执行thread.join()或在锁对象调用obj.wait()等情况就会进该状态,表明线程正处于等待某个资源或条件发生来唤醒自己;

Timed_Waiting:执行Thread.sleep(long)、thread.join(long)或obj.wait(long)等就会进该状态,与Waiting的区别在于Timed_Waiting的等待有时间限制;

Blocked:如果进入同步方法或同步代码块,没有获取到锁,则会进入该状态;

Dead:线程执行完毕,或者抛出了未捕获的异常之后,会进入dead状态,表示该线程结束

其次,对于jstack日志,我们要着重关注如下关键信息

Deadlock:表示有死锁

Waiting on condition:等待某个资源或条件发生来唤醒自己。具体需要结合jstacktrace来分析,比如线程正在sleep,网络读写繁忙而等待

Blocked:阻塞

Waiting on monitor entry:在等待获取锁

in Object.wait():获取锁后又执行obj.wait()放弃锁

对于Waiting on monitor entry 和 in Object.wait()的详细描述:Monitor是 Java中用以实现线程之间的互斥与协作的主要手段,它可以看成是对象或者 Class的锁。每一个对象都有,也仅有一个 monitor。从下图中可以看出,每个 Monitor在某个时刻,只能被一个线程拥有,该线程就是 "Active Thread",而其它线程都是 "Waiting Thread",分别在两个队列 " Entry Set"和 "Wait Set"里面等候。在 "Entry Set"中等待的线程状态是 "Waiting for monitor entry",而在 "Wait Set"中等待的线程状态是 "in Object.wait()"

6、总结:

对于jstack日志,我们要着重关注如下关键信息

Deadlock:表示有死锁

Waiting on condition:等待某个资源或条件发生来唤醒自己。具体需要结合jstacktrace来分析,比如线程正在sleep,网络读写繁忙而等待

Blocked:阻塞

Waiting on monitor entry:在等待获取锁

如果说系统慢,那么要特别关注Blocked,Waiting on condition

如果说系统的cpu耗的高,那么肯定是线程执行有死循环,那么此时要关注下Runable状态

相关文章: