jps 看java进程
语法
jps[options] [hostid]
options参数
-
-q :仅仅显示LVMID (local virtual machine id),即本地虚拟机唯一id。不显示主类的名称等
-
-1:输出应用程序主类的全类名或如果进程执行的是jar包,则输出jar完整路径
-
-m:输出虚拟机进程启动时传递给主类main()的参数
-
-v:列串虚拟机进程启动时的JVM参数。比如: -Xms20m-Xmx50m是启动程序指定的jvm参数。
说明:以上参数可以综合使用。
补充:
如果某Java进程关闭了默认开启的UsePerfData参数(即使用参数-XX:-UsePerfData) ,那么jps命令(以及下面介绍的jstat)将无法探知该Java进程。
jstat 统计监测JVM的gc信息
jstat(JVM Statistics Monitoring Tool): 用户监视虚拟机各种运行状态信息的命令行工具,它可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行的数据。
常用于检测垃圾回收以及内存泄漏问题。
语法:
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
option:行为
vmid:进程id
interval:用于指定输出统计数据的周期,单位为毫秒。即时间间隔。单位:毫秒
count:用于指定查询的总次数。
-t:可以输出信息前加上一个Timestamp列,显示程序运行时间。单位:秒。
-h:可以在周期性数据输出时,输出多少行数据后输出一个表头信息。
options
类装载相关:
- -class:显示ClassLoader的相关信息:类的装载、卸载数量、总空间、类装载所消耗的时间等
垃圾回收相关的:.
- -gc:显示与GC相关的堆信息。包括Eden区、两个Survivor区、老年代、永久代等的容量、,用空间、GC时间合计等信息。
- -gccapacity:显示内容与-gc基本相同,但输出主要关注Java堆各个区域使用到的最大、最小空间。
- gcutil:显示内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比。
- -gccause:与-gcutil功能一样,但是会额外输出导致最后一次或当前正在发生的GC产生的原因。
- -gcnew:显示新生代GC状况-
- gcnewcapacity:显示内容与-gcnew基本相同,输出主要关注使用到的最大、最小空间
- -geold:显示老年代GC状况
重点使用介绍:
jstat -class
jstat option vmid 默认 count 为1
root@server:~# jstat -class 8533
Loaded Bytes Unloaded Bytes Time
6646 11821.1 0 0.0 12.75
装载个数 字节数 卸载个数 字节数 使用时间
jstat option vmid interval
root@server:~# jstat -class 8533 1000
Loaded Bytes Unloaded Bytes Time
6703 11911.1 0 0.0 12.77
6703 11911.1 0 0.0 12.77
6703 11911.1 0 0.0 12.77
jstat option vmid interval count
root@server:~# jstat -class 8533 1000 10
Loaded Bytes Unloaded Bytes Time
6703 11911.1 0 0.0 12.77
6703 11911.1 0 0.0 12.77
6703 11911.1 0 0.0 12.77
6703 11911.1 0 0.0 12.77
6703 11911.1 0 0.0 12.77
6703 11911.1 0 0.0 12.77
6703 11911.1 0 0.0 12.77
6703 11911.1 0 0.0 12.77
6703 11911.1 0 0.0 12.77
6703 11911.1 0 0.0 12.77
root@server:~# jstat -class -t 8533
Timestamp Loaded Bytes Unloaded Bytes Time
590.7 6703 11911.1 0 0.0 12.77
程序从开始执行到现在一共多少秒 590.7 s
jstat option -h vmid interval count
root@server:~# jstat -class -t -h3 8533 1000 10
Timestamp Loaded Bytes Unloaded Bytes Time
738.0 6703 11911.1 0 0.0 12.77
739.0 6703 11911.1 0 0.0 12.77
740.0 6703 11911.1 0 0.0 12.77
Timestamp Loaded Bytes Unloaded Bytes Time
741.0 6703 11911.1 0 0.0 12.77
742.0 6703 11911.1 0 0.0 12.77
743.0 6703 11911.1 0 0.0 12.77
Timestamp Loaded Bytes Unloaded Bytes Time
744.0 6703 11911.1 0 0.0 12.77
745.0 6703 11911.1 0 0.0 12.77
746.0 6703 11911.1 0 0.0 12.77
Timestamp Loaded Bytes Unloaded Bytes Time
747.0 6703 11911.1 0 0.0 12.77
-h3 每隔3行输出一次表头
jstat -gc
root@server:~# jstat -gc 8533
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
10240.0 8192.0 0.0 0.0 249856.0 11848.7 35840.0 13983.8 36048.0 33375.8 4864.0 4371.3 9 1.776 2 0.312 2.088
root@server:~# jstat -gccause 8533 1000 10 gc的原因(这里是元空间)
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT LGCC GCC
0.00 0.00 4.74 39.02 92.59 89.87 9 1.776 2 0.312 2.088 Metadata GC Threshold No GC
0.00 0.00 4.74 39.02 92.59 89.87 9 1.776 2 0.312 2.088 Metadata GC Threshold No GC
0.00 0.00 4.74 39.02 92.59 89.87 9 1.776 2 0.312 2.088 Metadata GC Threshold No GC
0.00 0.00 4.74 39.02 92.59 89.87 9 1.776 2 0.312 2.088 Metadata GC Threshold No GC
0.00 0.00 4.74 39.02 92.59 89.87 9 1.776 2 0.312 2.088 Metadata GC Threshold No GC
0.00 0.00 4.74 39.02 92.59 89.87 9 1.776 2 0.312 2.088 Metadata GC Threshold No GC
0.00 0.00 4.74 39.02 92.59 89.87 9 1.776 2 0.312 2.088 Metadata GC Threshold No GC
0.00 0.00 4.74 39.02 92.59 89.87 9 1.776 2 0.312 2.088 Metadata GC Threshold No GC
0.00 0.00 4.74 39.02 92.59 89.87 9 1.776 2 0.312 2.088 Metadata GC Threshold No GC
0.00 0.00 4.74 39.02 92.59 89.87 9 1.776 2 0.312 2.088 Metadata GC Threshold No GC
单位:kb
列说明
S0C:第一个幸存区的大小
S1C:第二个幸存区的大小
S0U:第一个幸存区的使用大小
S1U:第二个幸存区的使用大小
EC:伊甸园区的大小
EU:伊甸园区的使用大小
OC:老年代大小
OU:老年代使用大小
MC:方法区大小
MU:方法区使用大小
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间 FGC时间+YGC时间
经验
可以通过比较进程的启动时间(Timestamp)和GC时间(GCT列),或者两次测量的间隔时间和总GC时间的增量,来得出GC时间占运行时间的比例。
如果该比例超过20%,则说明目前堆的压力比较大,如果该比例超过90%,则说明堆里几乎没有可用空间,随时都可能抛出OOM异常。
jinfo 实时查看和修改 JVM 配置参数值
jinfo(Configuralion Info for Java) : 查看虚拟机配置参数信息,也可用于调整虚拟机的配置参数。
在很多情况下,Java 应用程序不会指定所有的 Java 虚拟机参数。而此时,开发人员可能不知道某一个具体的 Java 虚拟机参数的默认值。
在这种情况下,可能需要通过查找文档获取某个参数的默认值。这个查找过程可能是非常艰难的。但有了 jinfo 工具,开发人员可以很方便地找到 Java 虚拟机参数的当前值。
基本语法
jinfo [ options ] pid
options
选项 | 选项说明 |
---|---|
no option | 输出全部的参数和系统属性 |
-flag name | 输出对应名称的参数 |
-flag [±]name | 开启或者关闭对应名称的参数只有被标记为 manageable 的参数才可以被动态修改 |
-flag name=value | 设定对应名称的参数 |
-flags | 输出全部的参数 |
-sysprops | 输出系统属性 |
常见用法
查看
jinfo -flags PID
查看曾经赋过值的一些参数
root@server:~# jinfo -flags 9290
JVM version is 25.191-b12
Non-default VM flags:
-XX:CICompilerCount=3 -XX:InitialHeapSize=62914560
-XX:MaxHeapSize=62914560 -XX:MaxNewSize=20971520
-XX:MinHeapDeltaBytes=524288 -XX:NewSize=20971520
-XX:OldSize=41943040 -XX:SurvivorRatio=8 -XX:+UseCompressedClassPointers
-XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps
-XX:-UseLargePagesIndividualAllocation
-XX:+UseParallelGC
Command line: -Xms60m -Xmx60m -XX:SurvivorRatio=8
jinfo -flag 具体参数 PID
root@server:~# jinfo -flag PrintGCDetails 9290
-XX:-PrintGCDetails
修改
jinfo 不仅可以查看运行时某一个 Java 虚拟机参数的实际取值,甚至可以在运行时修改部分参数,并使之立即生效。
但是,并非所有参数都支持动态修改。参数只有被标记为 manageable 的 flag 可以被实时修改。其实,这个修改能力是极其有限的。
可以查看被标记为 manageable 的参数。
针对 boolean 类型:
jinfo -flag [+-]具体参数 PID
root@server:~# jinfo -flag PrintGCDetails 9290
-XX:-PrintGCDetails
root@server:~# jinfo -flag +PrintGCDetails 9290
-XX:-PrintGCDetails
针对 非boolean 类型:
root@server:~# jinfo -flag MinHeapFreeRatio 9290-XX:MinHeapFreeRatio=0root@server:~# jinfo -flag MinHeapFreeRatio=1 9290root@server:~# jinfo -flag MinHeapFreeRatio 9290-XX:MinHeapFreeRatio=1
补充
java -XX+PrintFlagslnitial PID:查看所有 JVM 参数启动的初始值。
java -XX:+PrintFlagsFinal PID:查看所有 JVM 参数的最终值。
java -XX+PrintCommandLineFlags PID:查看已经被用户或者 JVM 设置过的详细参数名称和值
jmap 导出堆内存快照
jmap(JVM Memory Map) : 作用一方面是获取 dump 文件(堆转储快照文件,二进制文件),它还可以获取目标 Java 进程的内存相关信息,包括 Java堆各区域的使用情况、堆中对象的统计信息、类加载信息等。
基本语法
jmap [option] <pid>
(to connect to running process) 连接到正在运行的进程
jmap [option] <executable <core>
(to connect to a core file) 连接到核心文件
jmap [option] [server_id@]<remote server IP or hostname>
(to connect to remote debug server) 连接到远程调试服务
> pid: 目标进程的PID,进程编号,可以采用ps -ef | grep java 查看java进程的PID;
> executable: 产生core dump的java可执行程序;
> core: 将被打印信息的core dump文件;
> remote-hostname-or-IP: 远程debug服务的主机名或ip;
> server-id: 唯一id,假如一台主机上多个远程debug服务;
options
表头 | 表头 |
---|---|
-dump | 生成 dump 文件,-dump:live 只保存堆中存活的对象 |
-heap | 输出整个堆空间的详细信息,包括 GC 的使用、堆配置信息,以及内存的使用信息等 |
-histo | 输出堆空间中对象的统计信息,包括类、实例数量和合计容量 |
-permstat | 以 ClassLoader 为统计口径输出永久代的内存状态信息(仅 linux/solaris 平台有效) |
-finalizerinfo | 显示在 F-Queue 中等待 Finalizer 线程执行 finalize 方法的对象(仅 linux/solaris 平台有效) |
-F | 当虚拟机进程对-dump 选项没有任何响应时,强制执行生成 dump 文件(仅 linux/solaris 平台有效) |
说明:这些参数和 linux 下输入显示的命令多少会有不同,包括也受 jdk 版本的影响。
常见用法
输出dump文件(Java堆转储快照)
一般来说,使用 jmap 指令生成 dump 文件的操作算得上是最常用的 jmap 命令之一,将堆中所有存活对象导出至一个文件之中。
root@server:~# jmap -dump:live,format=b,file=order1.hprof 19570
root@server:~# ll
drwxr-xr-x 3 root root 4096 5月 26 06:27 order1.hprof
补充说明:
- Heap Dump 又叫做堆存储文件,指一个<font color=red> Java 进程在某个时间点的内存快照</font>。
- 通常在<font color=red>写 Heap Dump 文件前会触发一次 Full GC </font>, 所以 Heap Dump 文件里保存的都是 Full GC 后留下的对象信息。
- 由于生成 dump 文件比较耗时,大家需要耐心等待,尤其是大内存镜像生成的 dump 文件则需要耗费更长的时间来完成。
- 有些时候,通过命令行输出dump文件会来不及,当程序发生 OOM 退出系统时,一些瞬时信息都随着程序的终止而消失,而重现 OOM 问题往往比较困难或者耗时。这个时候就需要在OOM 时,自动导出 dump 文件。
- 启动参数:-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<filename.hprof>
打印heap的概要信息
jmap -heap PID
打印heap的概要信息,GC使用的算法,heap(堆)的配置及JVM堆内存的使用情况
using parallel threads in the new generation. ##新生代采用的是并行线程处理方式
using thread-local object allocation.
Concurrent Mark-Sweep GC ##同步并行垃圾回收
Heap Configuration: ##堆配置情况,也就是JVM参数配置的结果[平常说的tomcat配置JVM参数,就是在配置这些]
MinHeapFreeRatio = 40 ##最小堆使用比例
MaxHeapFreeRatio = 70 ##最大堆可用比例
MaxHeapSize = 2147483648 (2048.0MB) ##最大堆空间大小
NewSize = 268435456 (256.0MB) ##新生代分配大小
MaxNewSize = 268435456 (256.0MB) ##最大可新生代分配大小
OldSize = 5439488 (5.1875MB) ##老年代大小
NewRatio = 2 ##新生代比例
SurvivorRatio = 8 ##新生代与suvivor的比例
PermSize = 134217728 (128.0MB) ##perm区 永久代大小
MaxPermSize = 134217728 (128.0MB) ##最大可分配perm区 也就是永久代大小
Heap Usage: ##堆使用情况【堆内存实际的使用情况】
New Generation (Eden + 1 Survivor Space): ##新生代(伊甸区Eden区 + 幸存区survior(1+2)空间)
capacity = 241631232 (230.4375MB) ##伊甸区容量
used = 77776272 (74.17323303222656MB) ##已经使用大小
free = 163854960 (156.26426696777344MB) ##剩余容量
32.188004570534986% used ##使用比例
Eden Space: ##伊甸区
capacity = 214827008 (204.875MB) ##伊甸区容量
used = 74442288 (70.99369812011719MB) ##伊甸区使用
free = 140384720 (133.8813018798828MB) ##伊甸区当前剩余容量
34.65220164496263% used ##伊甸区使用情况
From Space: ##survior1区
capacity = 26804224 (25.5625MB) ##survior1区容量
used = 3333984 (3.179534912109375MB) ##surviror1区已使用情况
free = 23470240 (22.382965087890625MB) ##surviror1区剩余容量
12.43827838477995% used ##survior1区使用比例
To Space: ##survior2 区
capacity = 26804224 (25.5625MB) ##survior2区容量
used = 0 (0.0MB) ##survior2区已使用情况
free = 26804224 (25.5625MB) ##survior2区剩余容量
0.0% used ## survior2区使用比例
PS Old Generation: ##老年代使用情况
capacity = 1879048192 (1792.0MB) ##老年代容量
used = 30847928 (29.41887664794922MB) ##老年代已使用容量
free = 1848200264 (1762.5811233520508MB) ##老年代剩余容量
1.6416783843721663% used ##老年代使用比例
Perm Generation: ##永久代使用情况
capacity = 134217728 (128.0MB) ##perm区容量
used = 47303016 (45.111671447753906MB) ##perm区已使用容量
free = 86914712 (82.8883285522461MB) ##perm区剩余容量
35.24349331855774% used ##perm区使用比例
显示堆中对象统计信息
jmap -histo:live 71217
这个指令可以和一些指令联和使用
jmap -histo pid|head -n 10 查看前10位(<font color=red>在cpu满载的时候这个指令极为重要,jmap全输出在cpu满载的时候是极为困难的J</font>)
jmap -histo pid | sort -k 2 -g -r 查看对象数最多的对象,按降序输出
jmap -histo pid | sort -k 3 -g -r 查看内存的对象,按降序输出
查看存活对象
root@server:~# jmap -histo:live 1999|head -n 10
num #instances(实例数)#bytes(字节大小) class name
----------------------------------------------
1: 36060 3520384 [C
2: 36025 864600 java.lang.String
3: 7193 790832 java.lang.Class
4: 8458 744304 java.lang.reflect.Method
5: 21820 698240 java.util.concurrent.ConcurrentHashMap$Node
6: 2986 472512 [B
7: 9424 376960 java.util.LinkedHashMap$Entry
补充说明
jmap 需要借助安全点机制,让所有线程停留在不改变堆中数据的状态,这可能导致基于该堆快照的分析结果存在偏差。
jstack 打印 JVM 中线程快照
jstack(JVM stack Trace):用于生成虚拟机指定进程当前时刻的线程快照(虚拟机堆栈跟踪)。
补充说明
-
线程快照
- 当前虚拟机内指定进程的每一条线程正在执行的方法堆栈的集合。
-
生成线程快照的作用
- 可用于定位线程出现长时间停顿的原因,如<font color=red>线程间死锁、死循环、请求外部资源导致的长时间等待</font>等问题。
-
当线程出现停顿时,就可以用 jstack 显示各个线程调用的堆栈情况。
-
在 thread dump 中,要留意下面几种状态:
- 死锁,Deadlock (必须排查)
- 等待资源,Waiting on condition (重点关注)
- 等待获取监视器(锁),Waiting on monitor entry (重点关注)
- 阻塞,Blocked (必须排查)
- 执行中,Runnable
- 暂停,Suspended
- 对象等待中,Object.wait() 或 TIMED_WAITING
- 停止,Parked
基本语法
jstack [option] pid
options
参数 | 含义 |
---|---|
-F | 当正常输出的请求不被响应时,强制输出线程堆栈 |
-I | 除堆栈外,显示关于锁的附加信息 |
-m | 如果调用到本地方法,可以显示 C/C++的堆栈 |
-h | 帮助操作 |
案例
案例一:死锁
public static void main(String[] args) {
StringBuilder s1 = new StringBuilder();
StringBuilder s2 = new StringBuilder();
Thread thread1 = new Thread("线程1") {
@Override
public void run() {
synchronized (s1){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (s2){
System.out.println("我是"+Thread.currentThread().getName());
}
}
}
};
Thread thread2 = new Thread("线程2") {
@Override
public void run() {
synchronized (s2){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (s1){
System.out.println("我是"+Thread.currentThread().getName());
}
}
}
};
thread1.start();
thread2.start();
}
jstack
root@server:~# jstack 2193
2021-06-18 06:07:31
Full thread dump OpenJDK 64-Bit Server VM (25.292-b10 mixed mode):
"线程2" #31 prio=5 os_prio=0 tid=0x00007f0468a06000 nid=0x8b8 waiting for monitor entry [0x00007f0409f09000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.study.prometheus.PromethuesDemoApplication$2.run(PromethuesDemoApplication.java:74)
- waiting to lock <0x00000000ebb3abc0> (a java.lang.StringBuilder)
- locked <0x00000000ebb3ac08> (a java.lang.StringBuilder)
"线程1" #30 prio=5 os_prio=0 tid=0x00007f0468c96800 nid=0x8b7 waiting for monitor entry [0x00007f040a00a000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.study.prometheus.PromethuesDemoApplication$1.run(PromethuesDemoApplication.java:58)
- waiting to lock <0x00000000ebb3ac08> (a java.lang.StringBuilder)
- locked <0x00000000ebb3abc0> (a java.lang.StringBuilder)
"VM Thread" os_prio=0 tid=0x00007f04681c8000 nid=0x89b runnable
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f046801f800 nid=0x893 runnable
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007f0468021800 nid=0x894 runnable
"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007f0468023000 nid=0x895 runnable
"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007f0468025000 nid=0x896 runnable
"GC task thread#4 (ParallelGC)" os_prio=0 tid=0x00007f0468026800 nid=0x897 runnable
"GC task thread#5 (ParallelGC)" os_prio=0 tid=0x00007f0468028800 nid=0x898 runnable
"GC task thread#6 (ParallelGC)" os_prio=0 tid=0x00007f046802a000 nid=0x899 runnable
"GC task thread#7 (ParallelGC)" os_prio=0 tid=0x00007f046802c000 nid=0x89a runnable
"VM Periodic Task Thread" os_prio=0 tid=0x00007f0468215800 nid=0x8a4 waiting on condition
JNI global references: 1537
//快照里面会打印发现死锁
Found one Java-level deadlock:
=============================
"线程2":
waiting to lock monitor 0x00007f03c4002198 (object 0x00000000ebb3abc0, a java.lang.StringBuilder),
which is held by "线程1"
"线程1":
waiting to lock monitor 0x00007f0430004048 (object 0x00000000ebb3ac08, a java.lang.StringBuilder),
which is held by "线程2"
Java stack information for the threads listed above:
===================================================
"线程2":
at com.study.prometheus.PromethuesDemoApplication$2.run(PromethuesDemoApplication.java:74)
- waiting to lock <0x00000000ebb3abc0> (a java.lang.StringBuilder)
- locked <0x00000000ebb3ac08> (a java.lang.StringBuilder)
"线程1":
at com.study.prometheus.PromethuesDemoApplication$1.run(PromethuesDemoApplication.java:58)
- waiting to lock <0x00000000ebb3ac08> (a java.lang.StringBuilder)
- locked <0x00000000ebb3abc0> (a java.lang.StringBuilder)
Found 1 deadlock.
jstack -l
root@server:~# jstack -l 2193
2021-06-18 06:09:49
Full thread dump OpenJDK 64-Bit Server VM (25.292-b10 mixed mode):
"线程2" #31 prio=5 os_prio=0 tid=0x00007f0468a06000 nid=0x8b8 waiting for monitor entry [0x00007f0409f09000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.study.prometheus.PromethuesDemoApplication$2.run(PromethuesDemoApplication.java:74)
- waiting to lock <0x00000000ebb3abc0> (a java.lang.StringBuilder)
- locked <0x00000000ebb3ac08> (a java.lang.StringBuilder)
//这里会打印锁信息
Locked ownable synchronizers:
- None
"线程1" #30 prio=5 os_prio=0 tid=0x00007f0468c96800 nid=0x8b7 waiting for monitor entry [0x00007f040a00a000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.study.prometheus.PromethuesDemoApplication$1.run(PromethuesDemoApplication.java:58)
- waiting to lock <0x00000000ebb3ac08> (a java.lang.StringBuilder)
- locked <0x00000000ebb3abc0> (a java.lang.StringBuilder)
Locked ownable synchronizers:
- None
"Service Thread" #9 daemon prio=9 os_prio=0 tid=0x00007f0468213000 nid=0x8a3 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"C1 CompilerThread3" #8 daemon prio=9 os_prio=0 tid=0x00007f0468210000 nid=0x8a2 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"C2 CompilerThread2" #7 daemon prio=9 os_prio=0 tid=0x00007f046820e000 nid=0x8a1 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"C2 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007f046820c800 nid=0x8a0 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007f0468209800 nid=0x89f waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007f0468206800 nid=0x89e runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007f04681d6800 nid=0x89d in Object.wait() [0x00007f0439f6c000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000c31bad68> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
- locked <0x00000000c31bad68> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216)
Locked ownable synchronizers:
- None
"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007f04681d1800 nid=0x89c in Object.wait() [0x00007f043a06d000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000c31843e8> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x00000000c31843e8> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
Locked ownable synchronizers:
- None
"VM Thread" os_prio=0 tid=0x00007f04681c8000 nid=0x89b runnable
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f046801f800 nid=0x893 runnable
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007f0468021800 nid=0x894 runnable
"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007f0468023000 nid=0x895 runnable
"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007f0468025000 nid=0x896 runnable
"GC task thread#4 (ParallelGC)" os_prio=0 tid=0x00007f0468026800 nid=0x897 runnable
"GC task thread#5 (ParallelGC)" os_prio=0 tid=0x00007f0468028800 nid=0x898 runnable
"GC task thread#6 (ParallelGC)" os_prio=0 tid=0x00007f046802a000 nid=0x899 runnable
"GC task thread#7 (ParallelGC)" os_prio=0 tid=0x00007f046802c000 nid=0x89a runnable
"VM Periodic Task Thread" os_prio=0 tid=0x00007f0468215800 nid=0x8a4 waiting on condition
JNI global references: 1537
Found one Java-level deadlock:
=============================
"线程2":
waiting to lock monitor 0x00007f03c4002198 (object 0x00000000ebb3abc0, a java.lang.StringBuilder),
which is held by "线程1"
"线程1":
waiting to lock monitor 0x00007f0430004048 (object 0x00000000ebb3ac08, a java.lang.StringBuilder),
which is held by "线程2"
Java stack information for the threads listed above:
===================================================
"线程2":
at com.study.prometheus.PromethuesDemoApplication$2.run(PromethuesDemoApplication.java:74)
- waiting to lock <0x00000000ebb3abc0> (a java.lang.StringBuilder)
- locked <0x00000000ebb3ac08> (a java.lang.StringBuilder)
"线程1":
at com.study.prometheus.PromethuesDemoApplication$1.run(PromethuesDemoApplication.java:58)
- waiting to lock <0x00000000ebb3ac08> (a java.lang.StringBuilder)
- locked <0x00000000ebb3abc0> (a java.lang.StringBuilder)
Found 1 deadlock.
案例二:cpu满载
第一步:查看cpu占用高进程
top
Mem: 16333644k total, 9472968k used, 6860676k free, 165616k buffers
Swap: 0k total, 0k used, 0k free, 6665292k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
40433 root 20 0 7588m 112m 11m S 100.7 0.7 47:53.80 java
1552 root 20 0 121m 13m 8524 S 0.7 0.1 14:37.75 AliYunDun
3581 root 20 0 9750m 2.0g 13m S 0.7 12.9 298:30.20 java
1 root 20 0 19360 1612 1308 S 0.0 0.0 0:00.81 init
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
3 root RT 0 0 0 0 S 0.0 0.0 0:00.14 migration/0
第二步:查看高进程中cpu占用高线程
top -Hp 40433
top - 17:43:15 up 5 days, 7:31, 1 user, load average: 0.99, 0.97, 0.91
Tasks: 32 total, 1 running, 31 sleeping, 0 stopped, 0 zombie
Cpu(s): 3.7%us, 8.9%sy, 0.0%ni, 87.4%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 16333644k total, 9592504k used, 6741140k free, 165700k buffers
Swap: 0k total, 0k used, 0k free, 6781620k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
17880 root 20 0 7588m 112m 11m R 99.9 0.7 50:47.43 java
17856 root 20 0 7588m 112m 11m S 0.3 0.7 0:02.08 java
17850 root 20 0 7588m 112m 11m S 0.0 0.7 0:00.00 java
17851 root 20 0 7588m 112m 11m S 0.0 0.7 0:00.23 java
17852 root 20 0 7588m 112m 11m S 0.0 0.7 0:02.09 java
17853 root 20 0 7588m 112m 11m S 0.0 0.7 0:02.12 java
17854 root 20 0 7588m 112m 11m S 0.0 0.7 0:02.07 java
-H 显示线程信息,-p指定pid
第三步:转换线程ID
printf "%x\n" 40433
9df3
第四步:定位cpu占用线程
root@server:~# jstack -l 2193
40433 DBService-1.2.7.jar
20584 Server
37417 QuorumPeerMain
13705 jar
30892 Jps
[hh_mpp_cd@sjsy-hh305-hx13w ~]$ jstack 40433|grep -10 9df3
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
- locked <0x000000079df35438> (a org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
"http-nio-9372-exec-31" #5185 daemon prio=5 os_prio=0 tid=0x000000079df35438 nid=0x9df3 runnable [0x00007f86f9ad7000]
java.lang.Thread.State: RUNNABLE //cpu占用高 该线程状态应为RUNNABLE
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111)
at java.net.SocketOutputStream.write(SocketOutputStream.java:155)
--
"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007f879c526000 nid=0x9e15 in Object.wait() [0x00007f8732dec000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x00000006c00b4170> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
"VM Thread" os_prio=0 tid=0x00007f879c51c800 nid=0x9e14 runnable
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f879c01f000 nid=0x9df3 runnable //9df3 这个占用cpu高的线程为GC线程
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007f879c021000 nid=0x9df4 runnable
"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007f879c022800 nid=0x9df5 runnable
"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007f879c024800 nid=0x9df6 runnable
"GC task thread#4 (ParallelGC)" os_prio=0 tid=0x00007f879c026800 nid=0x9df7 runnable
"GC task thread#5 (ParallelGC)" os_prio=0 tid=0x00007f879c028000 nid=0x9df8 runnable
网友评论