jinfo -flag MaxHeapSize pid
查询到结果 478150656/1024/1024 = 456m 而不是32m
jinfo -flag MaxHeapSize pid
查询的结果是 java -XX:+PrintFinalFlags
中设置的最终 MaxHeapSize${IDEA}/bin/idea64.exe.vmoptions
# OS specific support. $var _must_ be set to either true or false. # OS specific support. $var _must_ be set to either true or false. JAVA_OPTS="-Xms256m -Xmx512m -Xss1024K -XX:PermSize=128m -XX:MaxPermSize=256m" cygwin=false
命令 | 全称 | 用途 |
---|---|---|
jps | JVM Process Status Tool | 显示指定系统内所有的HotSpot虚拟机进程 |
jinfo | Configuration Info for Java | 显示虚拟机配置信息 |
jstat | JVM Statistics Monitoring Tool | 用于收集Hotspot虚拟机各方面的运行数据 |
jmap | JVM Memory Map | 生成虚拟机的内存转储快照,生成heapdump文件 |
jhat | JVM Heap Dump Browser | 用于分析heapdump文件,它会建立一个HTTP/HTML服务器,让用户在浏览器上查看分析结果 |
jstack | JVM Stack Trace | 显示虚拟机的线程快照 |
类型名称 | 初始化堆空间大小 | 垃圾回收器 | 机器位数 | 备注信息 |
---|---|---|---|---|
Server VM | 大一些 | 并行 | 64-bit | - |
Client VM | 小一些 | 串行 | 32-bit | 在 64-bit 机器上无法切换到 Client VM 类型 |
JIT3 即时编译模式
JVM 内存结构 JDK 1.8
一级 | 二级 | 三级 |
---|---|---|
堆区 | 年轻代 | |
survival 0 | ||
survival 1 | ||
Eden | ||
老年代 | ||
非堆区 | Metaspace | |
CCS | ||
CodeCache |
一级 | 二级 | 三级 |
---|---|---|
堆区 | 年轻代 | |
survival 0 | ||
survival 1 | ||
Eden | ||
老年代 | ||
持久代 | 方法区 | |
其他 |
java -version:
java -Xms :是指程序启动时初始内存大小(此值可以设置成与-Xmx相同,以避免每次GC完成后 JVM 内存重新分配)
java -Xmx:指程序运行时最大可用内存大小,程序运行中内存大于这个值会 OutOfMemory
java -Xss :设置每个线程的堆栈大小
java -XX:+UseConcMarkSweepGC 并发标记清除(CMS)收集器8
java -XX:+UnlockExperimentalVMOptions 解锁实验参数
java -XX:+UnlockDiagnosticVMOptions 解锁诊断参数
java -XX:+PrintCommandLineFlags 用户手动设置或者JVM自动设置的XX选项
java -XX:+PrintFlagsInitial 打印出所有XX选项的默认值
java -XX:+PrintFlagsFinal 打印出XX选项在运行程序时生效的值
PID | CLASS | 含义 |
---|---|---|
18913 | Bootstrap | org.apache.catalina.startup.Bootstrap |
-Djava.util.logging.config.file=/root/apache-tomcat-8.5.37/conf/logging.properties | ||
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager | ||
-Djdk.tls.ephemeralDHKeySize=2048 | ||
-Djava.protocol.handler.pkgs=org.apache.catalina.webresources | ||
-Dorg.apache.catalina.security.SecurityListener.UMASK=0027 | ||
-Dignore.endorsed.dirs= -Dcatalina.base=/root/apache-tomcat-8.5.37 | ||
-Dcatalina.home=/root/apache-tomcat-8.5.37 | ||
-Djava.io.tmpdir=/root/apache-tomcat-8.5.37/temp | ||
19231 | Jps | sun.tools.jps.Jps |
-Denv.class.path=.:/usr/lib/jvm/java/lib/dt.jar:/usr/lib/jvm/java/lib/tools.jar:/usr/lib/jvm/java/jre/lib/rt.jar | ||
-Dapplication.home=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-1.el7_6.x86_64 -Xms8m |
jinfo -
基本命令格式-flag
: 打印指定java虚拟机的参数值-flag [+|-]
:设置或取消指定java虚拟机参数的布尔值-flag =
: 设置指定java虚拟机的参数的值-XX:MaxHeapSize=478150656
项目含义 | 对应命令 |
---|---|
类加载统计 | -class |
编译统计 | -compiler |
垃圾回收统计 | -gc |
堆内存统计 | -gccapacity |
新生代垃圾回收统计 | -gcnew |
新生代内存统计 | -gcnewcapacity |
老年代垃圾回收统计 | -gcold |
老年代内存统计 | -gcoldcapacity |
元数据空间统计 | -gcmetacapacity |
总结垃圾回收统计 | -gcutil |
JVM 编译方法统计 | -printcompilation |
[root@linux01 ~]# jstat -class 16971 10 10
Loaded Bytes Unloaded Bytes Time
4963 9887.1 0 0.0 6.53
4963 9887.1 0 0.0 6.53
4963 9887.1 0 0.0 6.53
4963 9887.1 0 0.0 6.53
4963 9887.1 0 0.0 6.53
4963 9887.1 0 0.0 6.53
4963 9887.1 0 0.0 6.53
4963 9887.1 0 0.0 6.53
4963 9887.1 0 0.0 6.53
4963 9887.1 0 0.0 6.53
名称 | 含义 |
---|---|
Loaded | 加载class的数量 |
Bytes | 所占用空间大小 |
Unloaded | 未加载数量 |
Bytes | 未加载占用空间 |
Time | 时间 |
[root@linux01 ~]# jstat -compiler 16971 10 10
Compiled Failed Invalid Time FailedType FailedMethod
2990 0 0 8.86 0
2990 0 0 8.86 0
2990 0 0 8.86 0
2990 0 0 8.86 0
2990 0 0 8.86 0
2990 0 0 8.86 0
2990 0 0 8.86 0
2990 0 0 8.86 0
2990 0 0 8.86 0
2990 0 0 8.86 0
名称 | 含义 |
---|---|
Loaded | 加载class的数量 |
Compiled | 编译数量。 |
Failed | 失败数量 |
Invalid | 不可用数量 |
Time | 时间 |
FailedType | 失败类型 |
FailedMethod | 失败的方法 |
[root@linux01 ~]# jstat -gc 16971 10 10
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
1344.0 1344.0 2.0 0.0 11136.0 655.4 27580.0 18048.6 30336.0 29551.2 3456.0 3307.3 86 0.281 2 0.077 0.358
1344.0 1344.0 2.0 0.0 11136.0 655.4 27580.0 18048.6 30336.0 29551.2 3456.0 3307.3 86 0.281 2 0.077 0.358
1344.0 1344.0 2.0 0.0 11136.0 655.4 27580.0 18048.6 30336.0 29551.2 3456.0 3307.3 86 0.281 2 0.077 0.358
1344.0 1344.0 2.0 0.0 11136.0 655.4 27580.0 18048.6 30336.0 29551.2 3456.0 3307.3 86 0.281 2 0.077 0.358
1344.0 1344.0 2.0 0.0 11136.0 655.4 27580.0 18048.6 30336.0 29551.2 3456.0 3307.3 86 0.281 2 0.077 0.358
1344.0 1344.0 2.0 0.0 11136.0 655.4 27580.0 18048.6 30336.0 29551.2 3456.0 3307.3 86 0.281 2 0.077 0.358
1344.0 1344.0 2.0 0.0 11136.0 655.4 27580.0 18048.6 30336.0 29551.2 3456.0 3307.3 86 0.281 2 0.077 0.358
1344.0 1344.0 2.0 0.0 11136.0 655.4 27580.0 18048.6 30336.0 29551.2 3456.0 3307.3 86 0.281 2 0.077 0.358
1344.0 1344.0 2.0 0.0 11136.0 655.4 27580.0 18048.6 30336.0 29551.2 3456.0 3307.3 86 0.281 2 0.077 0.358
1344.0 1344.0 2.0 0.0 11136.0 655.4 27580.0 18048.6 30336.0 29551.2 3456.0 3307.3 86 0.281 2 0.077 0.358
名称 | 含义 |
---|---|
S0C | 第一个幸存区的大小 |
S1C | 第二个幸存区的大小 |
S0U | 第一个幸存区的使用大小 |
S1U | 第二个幸存区的使用大小 |
EC | 伊甸园区的大小 |
EU | 伊甸园区的使用大小 |
OC | 老年代大小 |
OU | 老年代使用大小 |
MC | 方法区大小 |
MU | 方法区使用大小 |
CCSC | 压缩类空间大小 |
CCSU | 压缩类空间使用大小 |
YGC | 年轻代垃圾回收次数 |
YGCT | 年轻代垃圾回收消耗时间 |
FGC | 老年代垃圾回收次数 |
FGCT | 老年代垃圾回收消耗时间 |
GCT | 垃圾回收消耗总时间 |
jmap -dump:format=b,file=filename pid
package com.ssm.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* 模拟内存溢出场景
* @author study
*/
@Controller
@RequestMapping("/memory")
public class MemoryController {
private List userList = new ArrayList();
/**
* 模拟堆溢出异常
* JVM 运行环境设置 -Xmx 32M -Xms 32M
*/
@RequestMapping("/heap")
public void heap(){
int index = 0 ;
while (true){
userList.add(new User(index++, UUID.randomUUID().toString()));
}
}
/**
* 用户信息实体类
*/
public class User{
public User(Integer id ,String name){
this.id = id ;
this.name = name ;
}
/**
* 用户编号
*/
private Integer id ;
/**
* 用户姓名
*/
private String name ;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
private List classList = new ArrayList();
/**
* 模拟方法区溢出异常
* JVM 运行环境设置 -XX:MetaspaceSize=32M --XX:MaxMetaspaceSize=32M
* JDK 1.8
*/
@RequestMapping("/method")
public void method(){
// 通过 ASM 动态生成 Class 文件,存入 classList 中
}
}
-XX:+HeapDumpOnOutOfMemoryError 当发生内存溢出时将文件dump出来 -XX:HeapDumpPath=./
[root@linux01 bin]# jinfo -flag HeapDumpOnOutOfMemoryError 16964
-XX:-HeapDumpOnOutOfMemoryError
[root@linux01 bin]# jinfo -flag +HeapDumpOnOutOfMemoryError 16964
[root@linux01 bin]# jinfo -flag HeapDumpOnOutOfMemoryError 16964
-XX:+HeapDumpOnOutOfMemoryError
[root@linux01 bin]# jinfo -flag HeapDumpPath=./ 16964
[root@linux01 bin]# jinfo -flag HeapDumpPath 16964
-XX:HeapDumpPath=./
运行:
修改 JVM 环境配置:修改 tomcat/bin/catalina.sh 文件添加 JAVA_OPTS
访问 http://192.168.255.100:8080/memory/heap
执行 jmap -dump:format=b,file=managed_heapdump.hprof pid
内存溢出时自动检出文件配置
将映像文件从服务中导出到 Windows 环境
分析:使用 mat (Memory Analyzer Tool)工具分析内存映像文件
总结: 生产环境分析内存溢出更加复杂,要逐个对象查看强引用对象的引用,逐步定位问题
MAT 使用方法16 17 18
jmap -histo pid 展示class的内存情况
jmap -finalizerinfo pid 打印等待回收的对象信息
jmap -heap pid 打印堆信息
堆转储文件实现方式
package com.ssm.controller;
import com.ssm.biz.thread.Blocked;
import com.ssm.biz.thread.DeadLock;
import javafx.concurrent.Task;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 模拟线程异常场景
* @author study
*/
@Controller
@RequestMapping("/thread")
public class ThreadController {
/**
* 模拟死锁场景
* @return 跳转首页
*/
@RequestMapping("/deadLock")
public String deadLock(){
Thread thread1 = new Thread(new DeadLock(),"thread-1");
Thread thread2 = new Thread(new DeadLock(),"thread-2");
thread1.start();
thread2.start();
return "index";
}
private ExecutorService es = Executors.newFixedThreadPool(5);
/**
* 模拟资源竞争
* @return 跳转首页
*/
@RequestMapping("blocked")
public String blocked(){
Blocked b1 = new Blocked();
Blocked b2 = new Blocked();
es.execute(b1);
es.execute(b2);
return "index";
}
}
package com.ssm.biz.thread;
/**
* @author study
* 模拟死锁
*/
public class DeadLock implements Runnable{
private static Object lock1 = new Object();
private static Object lock2 = new Object();
private static boolean flag ;
public void run() {
System.out.println(Thread.currentThread().getName()+" running");
if(flag){
synchronized (lock1){
System.out.println(Thread.currentThread().getName()+" acquire lock1");
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock2){
System.out.println(Thread.currentThread().getName()+" acquire lock2");
}
}
}else{
synchronized (lock2){
System.out.println(Thread.currentThread().getName()+" acquire lock2");
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock1){
System.out.println(Thread.currentThread().getName()+" acquire lock1");
}
}
}
}
}
package com.ssm.biz.thread;
/**
* @author study
*/
public class Blocked implements Runnable{
private static Object lock = new Object();
public void run() {
synchronized (lock){
Integer index = 0 ;
while (true){
index++;
}
}
}
}
[root@linux01 bin]# top -Hp 18824
Threads: 43 total, 0 running, 43 sleeping, 0 stopped, 0 zombie
%Cpu(s): 10.0 us, 0.7 sy, 0.0 ni, 89.2 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 1863224 total, 488064 free, 288600 used, 1086560 buff/cache
KiB Swap: 2097148 total, 2097148 free, 0 used. 1347608 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
18830 root 20 0 2549200 145280 16128 S 6.6 7.8 0:09.08 java
18858 root 20 0 2549200 145280 16128 S 4.7 7.8 0:00.18 java
18851 root 20 0 2549200 145280 16128 S 3.0 7.8 0:00.39 java
18831 root 20 0 2549200 145280 16128 S 1.7 7.8 0:02.64 java
18842 root 20 0 2549200 145280 16128 S 0.3 7.8 0:00.37 java
18824 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.00 java
18825 root 20 0 2549200 145280 16128 S 0.0 7.8 0:01.63 java
18826 root 20 0 2549200 145280 16128 S 0.0 7.8 0:01.27 java
18827 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.00 java
18828 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.01 java
18829 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.00 java
18832 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.00 java
18833 root 20 0 2549200 145280 16128 S 0.0 7.8 0:15.71 java
18834 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.46 java
18837 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.00 java
18841 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.32 java
18850 root 20 0 2549200 145280 16128 S 0.0 7.8 0:01.81 java
18852 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.00 java
18853 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.00 java
18854 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.00 java
18855 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.00 java
18856 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.00 java
18857 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.00 java
18859 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.01 java
18860 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.00 java
18862 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.44 java
18863 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.04 java
18864 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.42 java
18865 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.00 java
18866 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.00 java
18867 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.00 java
18868 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.00 java
18869 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.00 java
18870 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.00 java
18871 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.00 java
18872 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.01 java
18873 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.02 java
18874 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.00 java
18875 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.48 java
18876 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.00 java
18877 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.58 java
18911 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.00 java
19269 root 20 0 2549200 145280 16128 S 0.0 7.8 0:00.00 java
[root@linux01 ~]# printf "%x" 18830
498e[root@linux01 ~]# jstack 18824 | grep "498e" -A 20
"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007f93f0113000 nid=0x498e waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007f93f0106000 nid=0x498d runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007f93f00da800 nid=0x498c in Object.wait() [0x00007f93e042d000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000ed1799f0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
- locked <0x00000000ed1799f0> (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)
"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007f93f00d6000 nid=0x498b in Object.wait() [0x00007f93e052e000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000ed179ba8> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
[root@linux01 ~]# printf "%x" 18858
49aa[root@linux01 ~]# jstack 18824 | grep "49aa" -A 20
"http-nio-8080-exec-8" #24 daemon prio=5 os_prio=0 tid=0x00007f93f039f800 nid=0x49aa waiting on condition [0x00007f93bd921000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000ee224328> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
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-8080-exec-7" #23 daemon prio=5 os_prio=0 tid=0x00007f93f039c800 nid=0x49a9 waiting on condition [0x00007f93bda22000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000ee224328> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
[root@linux01 ~]# printf "%x\n" 18851
49a3
[root@linux01 ~]# jstack 18824 | grep "49a3" -A 20
"http-nio-8080-exec-1" #17 daemon prio=5 os_prio=0 tid=0x00007f93f0424000 nid=0x49a3 waiting on condition [0x00007f93be028000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000ee224328> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
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)
"ContainerBackgroundProcessor[StandardEngine[Catalina]]" #16 daemon prio=5 os_prio=0 tid=0x00007f93f01ad000 nid=0x49a2 waiting on condition [0x00007f93be342000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1359)
at java.lang.Thread.run(Thread.java:748)
[root@linux01 ~]# printf "%x" 18831
498f[root@linux01 ~]# jstack 18824 | grep "498f" -A 20
"C1 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007f93f0115000 nid=0x498f waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007f93f0113000 nid=0x498e waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007f93f0106000 nid=0x498d runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007f93f00da800 nid=0x498c in Object.wait() [0x00007f93e042d000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000ed1799f0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
- locked <0x00000000ed1799f0> (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)
"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007f93f00d6000 nid=0x498b in Object.wait() [0x00007f93e052e000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
堆栈信息,导出堆栈信息 jstack pid > a.txt
“” 线程名称,多线程开发时尽量给线程命名,查询堆栈信息时便于定位问题
#
堆栈深度
daemon 系统守护线程,查询堆栈信息时主要查看用户线程,非守护线程
prio JVM 线程优先级
os_prio OS,Operation System 本地操作系统中线程优先级
tid JVM 线程编号
nid native 本地操作系统线程编号
[]
java.lang.Thread.State
java 线程堆栈信息
线程示例23
[root@linux01 ~]# jstack 19466 | grep "BLOCKED" -C 20
2019-02-21 02:52:19
Full thread dump OpenJDK 64-Bit Server VM (25.191-b12 mixed mode):
"Attach Listener" #46 daemon prio=9 os_prio=0 tid=0x00007f9a60002000 nid=0x4c59 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"pool-1-thread-2" #45 prio=5 os_prio=0 tid=0x00007f9a885db000 nid=0x4c4d waiting for monitor entry [0x00007f9a64d01000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.ssm.biz.thread.Blocked.run(Blocked.java:12)
- waiting to lock <0x00000000ee2509d0> (a java.lang.Object)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
"pool-1-thread-1" #44 prio=5 os_prio=0 tid=0x00007f9a885da800 nid=0x4c4c waiting on condition [0x00007f9a64e02000]
java.lang.Thread.State: RUNNABLE
at java.lang.Integer.valueOf(Integer.java:832)
at com.ssm.biz.thread.Blocked.run(Blocked.java:16)
- locked <0x00000000ee2509d0> (a java.lang.Object)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
"ajp-nio-8009-AsyncTimeout" #42 daemon prio=5 os_prio=0 tid=0x00007f9a882b0000 nid=0x4c3e waiting on condition [0x00007f9a55f07000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at org.apache.coyote.AbstractProtocol$AsyncTimeout.run(AbstractProtocol.java:1149)
at java.lang.Thread.run(Thread.java:748)
线程状态 | 产生动作 | 堆栈信息 | 状态含义 | 备注信息 |
---|---|---|---|---|
NEW | new Thread | 无 | 线程已经创建,但未调用start()方法 | jstack命令不会列出处于此状态的线程信息 |
RUNNABLE | start() | java.lang.Thread.State: RUNNABLE | ||
Executor.execute() | ||||
BLOCKED | synchronize(lock) | java.lang.Thread.State: BLOCKED (on object monitor) | 正在等待一个monitor lock 通常情况下,是因为本线程与其他线程公用了一个锁。其他在线程正在使用这个锁进入某个synchronized同步方法块或者方法,而本线程进入这个同步代码块也需要这个锁,最终导致本线程处于阻塞状态 | |
WAITING | java.lang.Thread.State: WAITING (on object monitor) | Object.wait | ||
Thread.join | ||||
LockSupport.park | java.lang.Thread.State: WAITING (parking) | |||
TIMED_WAITING | Thread.sleep | java.lang.Thread.State: TIMED_WAITING (sleeping) | ||
Object.wait | java.lang.Thread.State: TIMED_WAITING (on object monitor) | |||
Thread.join with timeout | ||||
LockSupport.parkNanos | java.lang.Thread.State: TIMED_WAITING (parking) | |||
LockSupport.parkUntil | java.lang.Thread.State: TIMED_WAITING (parking) | |||
TERMINATED | 线程终止 |
JDK 工具 ↩︎
JDK中的命令行工具 ↩︎
JIT——即时编译的原理 ↩︎
Hotspot JVM的常用选项 ↩︎
深入理解Java语言 ↩︎
TM (商标标志) ↩︎
Sun HotSpot VM ↩︎
Java内存与垃圾回收调优 ↩︎
java jps 命令详解 ↩︎
JPS ↩︎
jinfo命令使用 ↩︎
jstat命令使用 ↩︎
java命令–jmap命令使用 ↩︎
IDEA用maven创建springMVC项目和配置 ↩︎
Class文件格式实战:使用ASM动态生成class文件 ↩︎
内存泄漏检测分析工具MAT(Memory Analyzer Tool)的使用 ↩︎
Java程序内存分析:使用mat工具分析内存占用 ↩︎
7.1 :OutOfMemoryError,Java堆溢出了,这表明程序有严重的问题。我们需要找造成OutOfMemoryError原因。一般有两种情况 ↩︎
Java Heap dump文件分析工具jhat简介 ↩︎
jdk工具之jhat命令(Java Heap Analyse Tool 虚拟机堆转储快照分析工具)、jhat之一:对dump的结果在浏览器上展示 ↩︎
JVM源码分析之synchronized实现 ↩︎
Linux线程优先级 ↩︎
如何使用jstack分析线程状态 ↩︎
jstack ↩︎
jstack简介 ↩︎
三、jdk工具之jstack(Java Stack Trace) ↩︎
jconsole与jvisualvm ↩︎