jps 用来查看JVM里面所有进程的具体状态, 包括进程ID,进程启动的路径等等。
jinfo–可以知道崩溃的JVM参数配置信息及JDK版本安装路径等信息。
jstat– JVM内建的指令对Java应用程序的资源和性能进行实时的命令行的监控,包括了对Heap size和垃圾回收状况的监控等等。
jmap+jhat–jmap可以生成堆转储快照文件,jhat可以查看快照文件分析内存溢出可能的原因。
jstack-- 获取JVM当前线程,JVM内每个线程正在执行方法的栈信息,包括线程状态,什么线程操作导致当前线程状态。
jdb– jdb 用来对core文件和正在运行的Java进程进行实时地调试,里面包含了丰富的命令帮助您进行调试,它的功能和Sun studio里面所带的dbx非常相似,但 jdb是专门用来针对Java应用程序的。
jconsole– jconsole是基于Java Management Extensions (JMX)的实时图形化监测工具,这个工具利用了内建到JVM里面的JMX指令来提供实时的性能和资源的监控,包括了Java程序的内存使用,Heap size, 线程的状态,类的分配状态和空间使用等等。
1.jps
实际中这是最常用的命令,下面要介绍的小工具更多的都是先要使用jps查看出当前有哪些Java进程,获取该Java进程的id后再对该进程进行处理。
jps主要用来输出JVM中运行的进程状态信息。
语法格式如下:
jps [options] [hostid]
如果不指定hostid就默认为当前主机或服务器。
参数解释:
-q 不输出类名、Jar名和传入main方法的参数
-m 输出传入main方法的参数
-l 输出main类或Jar的全限名
-v 输出传入JVM的参数
C:\Users\kpion>JPS
18704
23360 Jps
13496 Launcher
17324 DemoApplication
5756 JConsole
7196 Main
2.jstat
JVM统计监测工具
jstat可以实时显示本地或远程JVM进程中类装载、内存、垃圾收集、JIT编译等数据(如果要显示远程JVM信息,需要远程主机开启RMI支持)。
如果在服务启动时没有指定启动参数-verbose:gc,则可以用jstat实时查看gc情况。
命令格式:jstat [option vmid [interval[s|ms] [count]]]
参数解释:
Options — 选项,我们一般使用 -gcutil 查看gc情况
vmid — VM的进程号,即当前运行的java进程号
interval– 间隔时间,单位为秒或者毫秒
count — 打印次数,如果缺省则打印无数次
-class:
监视类装载、卸载数量、总空间及类装载所耗费的时间
-gc:
监听Java堆状况,包括Eden区、两个Survivor区、老年代、永久代等的容量,以用空间、GC时间合计等信息
-gccapacity:
监视内容与-gc基本相同,但输出主要关注java堆各个区域使用到的最大和最小空间
-gcutil:
监视内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比如S0为86.53,代表着S0区已使用了86.53%
-gccause:
与-gcutil功能一样,但是会额外输出导致上一次GC产生的原因
-gcnew:
监视新生代GC状况
-gcnewcapacity:
监视内同与-gcnew基本相同,输出主要关注使用到的最大和最小空间
-gcold:
监视老年代GC情况
-gcoldcapacity:
监视内同与-gcold基本相同,输出主要关注使用到的最大和最小空间
-gcpermcapacity:
输出永久代使用到最大和最小空间
-compiler:
输出JIT编译器编译过的方法、耗时等信息
-printcompilation:
输出已经被JIT编译的方法
一些术语的中文解释:
S0C:S0区容量(S1区相同,略)
S0U:S0区已使用
EC:E区容量
EU:E区已使用
OC:老年代容量
OU:老年代已使用
PC:Perm容量
PU:Perm区已使用
YGC:Young GC(Minor GC)次数
YGCT:Young GC总耗时
FGC:Full GC次数
FGCT:Full GC总耗时
GCT:GC总耗时
C:\Users\kpion>jstat -gc 17324
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
17920.0 17920.0 0.0 11704.0 161280.0 119852.1 247296.0 31790.9 74968.0 72899.0 6912.0 6416.6 9 0.081 3 0.192 0.273
C:\Users\kpion>jstat -gc 17324 5
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
17920.0 17920.0 0.0 11704.0 161280.0 139274.2 247296.0 31790.9 74968.0 72899.0 6912.0 6416.6 9 0.081 3 0.192 0.273
17920.0 17920.0 0.0 11704.0 161280.0 139274.2 247296.0 31790.9 74968.0 72899.0 6912.0 6416.6 9 0.081 3 0.192 0.273
17920.0 17920.0 0.0 11704.0 161280.0 139274.2 247296.0 31790.9 74968.0 72899.0 6912.0 6416.6 9 0.081 3 0.192 0.273
17920.0 17920.0 0.0 11704.0 161280.0 139274.2 247296.0 31790.9 74968.0 72899.0 6912.0 6416.6 9 0.081 3 0.192 0.273
17920.0 17920.0 0.0 11704.0 161280.0 139274.2 247296.0 31790.9 74968.0 72899.0 6912.0 6416.6 9 0.081 3 0.192 0.273
省略...
C:\Users\kpion>jstat -gcutil 17324
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
91.55 0.00 19.07 12.87 97.16 93.92 12 0.183 3 0.192 0.375
3.jstack
jstack能得到运行java程序的java stack和native stack的信息。可以轻松得知当前线程的运行情况。
Usage:
jstack [-l]
(to connect to running process) 连接活动线程
jstack -F [-m] [-l]
(to connect to a hung process) 连接阻塞线程
jstack [-m] [-l]
(to connect to a core file) 连接dump的文件
jstack [-m] [-l] [server_id@]
(to connect to a remote debug server) 连接远程服务器
Options:
-F to force a thread dump. Use when jstack does not respond (process is hung)
-m to print both java and native frames (mixed mode)
-l long listing. Prints additional information about locks
-h or -help to print this help message
结合top和jstack找出占用cpu最高的堆栈信息
1,使用命令top -p
2,按H,获取每个线程的内存情况
3,找到内存和cpu占用最高的线程pid,比如4977
4,转为16进制得到 0x1371 ,此为线程id的十六进制
5,执行 jstack 4977|grep -A 10 1371,得到线程堆栈信息中1371这个线程所在行的后面10行
6,查看对应的堆栈信息找出可能存在问题的代码
[root@iZ2ze4v2sdd3vdp1ne5smhZ ~]# jps
10736 QuorumPeerMain
10768 QuorumPeerMain
11058 QuorumPeerMain
22402 Bootstrap
21596 Jps
[root@iZ2ze4v2sdd3vdp1ne5smhZ ~]# top -p 11058
我选了11072这个pid,转16进制为2b40
在thread dump中,要留意下面几种状态
1. 死锁,Deadlock(重点关注)
2. 执行中,Runnable
3. 等待资源,Waiting on condition(重点关注)
4. 等待获取监视器,Waiting on monitor entry(重点关注)
5. 暂停,Suspended
6. 对象等待中,Object.wait() 或 TIMED_WAITING
7. 阻塞,Blocked(重点关注)
- 停止,Parked
jstack -l 17324
2020-02-22 12:07:11
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.231-b11 mixed mode):
"RMI TCP Connection(11)-192.168.0.105" #65 daemon prio=5 os_prio=0 tid=0x0000000020f7c000 nid=0x38b8 runnable [0x000000000079d000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:178)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:249)
at java.io.BufferedInputStream.read(BufferedInputStream.java:265)
- locked <0x000000076e791618> (a java.io.BufferedInputStream)
at java.io.FilterInputStream.read(FilterInputStream.java:83)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:556)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:857)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$390/1850215416.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:692)
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)
Locked ownable synchronizers:
- <0x000000076e70bb18> (a java.util.concurrent.ThreadPoolExecutor$Worker)
"RMI TCP Connection(9)-192.168.0.105" #63 daemon prio=5 os_prio=0 tid=0x0000000020f77800 nid=0x27ac in Object.wait() [0x0000000026bbc000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at com.sun.jmx.remote.internal.ArrayNotificationBuffer.fetchNotifications(ArrayNotificationBuffer.java:481)
- locked <0x00000007790080a0> (a com.sun.jmx.remote.internal.ArrayNotificationBuffer)
at com.sun.jmx.remote.internal.ArrayNotificationBuffer$ShareBuffer.fetchNotifications(ArrayNotificationBuffer.java:227)
at com.sun.jmx.remote.internal.ServerNotifForwarder.fetchNotifs(ServerNotifForwarder.java:277)
at javax.management.remote.rmi.RMIConnectionImpl$4.run(RMIConnectionImpl.java:1270)
at javax.management.remote.rmi.RMIConnectionImpl$4.run(RMIConnectionImpl.java:1268)
at javax.management.remote.rmi.RMIConnectionImpl.fetchNotifications(RMIConnectionImpl.java:1276)
at sun.reflect.GeneratedMethodAccessor123.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:367)
at sun.rmi.transport.Transport$1.run(Transport.java:200)
at sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:210)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:580)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:857)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$390/1850215416.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:692)
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)
Locked ownable synchronizers:
- <0x0000000779010800> (a java.util.concurrent.ThreadPoolExecutor$Worker)
jstack检测死锁
死锁代码
public class DeadLock {
public static void main(String[] args) {
System.out.println(" start the example ----- ");
final Object obj_1 = new Object(), obj_2 = new Object();
Thread t1 = new Thread("t1") {
@Override
public void run() {
synchronized (obj_1) {
try {
System.out.println("thread t1 start...");
Thread.sleep(3000);
} catch (InterruptedException e) {e.printStackTrace();}
synchronized (obj_2) {
System.out.println("thread t1 done....");
}
}
}
};
Thread t2 = new Thread("t2") {
@Override
public void run() {
synchronized (obj_2) {
try {
System.out.println("thread t2 start...");
Thread.sleep(3000);
} catch (InterruptedException e) {e.printStackTrace();}
synchronized (obj_1) {
System.out.println("thread t2 done...");
}
}
}
};
t1.start();
t2.start();
}
}
C:\Users\kpion>jps
13488 Jps
13984 DeadLock
18704
21464 Launcher
17324 DemoApplication
5756 JConsole
7196 Main
C:\Users\kpion> jstack -l 13984
...省略
Found one Java-level deadlock:
=============================
"t2":
waiting to lock monitor 0x000000001c5b3608 (object 0x000000076b77dcb8, a java.lang.Object),
which is held by "t1"
"t1":
waiting to lock monitor 0x000000001c5b0d78 (object 0x000000076b77dcc8, a java.lang.Object),
which is held by "t2"
Java stack information for the threads listed above:
===================================================
"t2":
at com.kpioneer.demo.DeadLock$2.run(DeadLock.java:39)
- waiting to lock <0x000000076b77dcb8> (a java.lang.Object)
- locked <0x000000076b77dcc8> (a java.lang.Object)
"t1":
at com.kpioneer.demo.DeadLock$1.run(DeadLock.java:23)
- waiting to lock <0x000000076b77dcc8> (a java.lang.Object)
- locked <0x000000076b77dcb8> (a java.lang.Object)
Found 1 deadlock.
继续使用jstack来分析HashMap在多线程情况下的死锁问题:
对于如下代码,使用10个线程来处理提交的2000个任务,每个任务会分别循环往hashmap中分别存入和取出1000个数,通过测试发现,程序并不能完整执行完成
2020-02-22 14:33:18
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.231-b11 mixed mode):
"DestroyJavaVM" #22 prio=5 os_prio=0 tid=0x000000001f82f800 nid=0x1d00 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"pool-1-thread-10" #21 prio=5 os_prio=0 tid=0x000000001f7e7800 nid=0x2edc waiting on condition [0x000000002097f000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at com.kpioneer.demo.HashMapDeadLock.call(HashMapDeadLock.java:31)
at com.kpioneer.demo.HashMapDeadLock.call(HashMapDeadLock.java:15)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
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)
Locked ownable synchronizers:
- <0x000000076f5007a0> (a java.util.concurrent.ThreadPoolExecutor$Worker)
"pool-1-thread-9" #20 prio=5 os_prio=0 tid=0x000000001f7e7000 nid=0x4a80 waiting on condition [0x000000002087f000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at com.kpioneer.demo.HashMapDeadLock.call(HashMapDeadLock.java:31)
at com.kpioneer.demo.HashMapDeadLock.call(HashMapDeadLock.java:15)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
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)
Locked ownable synchronizers:
- <0x000000076f508c30> (a java.util.concurrent.ThreadPoolExecutor$Worker)
死循环
public class EndlessLoop {
public static void main(String[] args) throws InterruptedException {
while (true) {
}
}
}
C:\Users\kpion>jps
13984 DeadLock
17136 Launcher
18704
18100 EndlessLoop
23460 Jps
17324 DemoApplication
5756 JConsole
7196 Main
C:\Users\kpion>jstack -l 18100 > endless.jstack
2020-02-22 15:31:42
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.231-b11 mixed mode):
"Service Thread" #11 daemon prio=9 os_prio=0 tid=0x000000001eb6b800 nid=0x3514 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"C1 CompilerThread3" #10 daemon prio=9 os_prio=2 tid=0x000000001eac8000 nid=0x1680 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"C2 CompilerThread2" #9 daemon prio=9 os_prio=2 tid=0x000000001eac3000 nid=0x1d50 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"C2 CompilerThread1" #8 daemon prio=9 os_prio=2 tid=0x000000001eabf800 nid=0x4e24 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"C2 CompilerThread0" #7 daemon prio=9 os_prio=2 tid=0x000000001eabc800 nid=0x4f88 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Monitor Ctrl-Break" #6 daemon prio=5 os_prio=0 tid=0x000000001ea9d800 nid=0x4a34 runnable [0x000000001f12e000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
- locked <0x000000076b84a2a8> (a java.io.InputStreamReader)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
- locked <0x000000076b84a2a8> (a java.io.InputStreamReader)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)
Locked ownable synchronizers:
- None
"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x000000001e8c1000 nid=0x2460 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x000000001e86a000 nid=0x2fd4 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x000000001e851800 nid=0x3790 in Object.wait() [0x000000001ee2e000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000076b588ed8> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
- locked <0x000000076b588ed8> (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=2 tid=0x000000001e850800 nid=0x587c in Object.wait() [0x000000001ed2e000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000076b586c00> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x000000076b586c00> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
Locked ownable synchronizers:
- None
"main" #1 prio=5 os_prio=0 tid=0x0000000002f74800 nid=0x178c runnable [0x0000000002daf000]
java.lang.Thread.State: RUNNABLE
at com.kpioneer.demo.EndlessLoop.main(EndlessLoop.java:10)
Locked ownable synchronizers:
- None
"VM Thread" os_prio=2 tid=0x000000001ca59800 nid=0x57cc runnable
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x0000000002f8a800 nid=0x628 runnable
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x0000000002f8c000 nid=0x45f4 runnable
"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x0000000002f8d800 nid=0x5aec runnable
"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x0000000002f8f000 nid=0x37cc runnable
"GC task thread#4 (ParallelGC)" os_prio=0 tid=0x0000000002f91800 nid=0x43e0 runnable
"GC task thread#5 (ParallelGC)" os_prio=0 tid=0x0000000002f93800 nid=0x4704 runnable
"GC task thread#6 (ParallelGC)" os_prio=0 tid=0x0000000002f97000 nid=0x2cf0 runnable
"GC task thread#7 (ParallelGC)" os_prio=0 tid=0x0000000002f98000 nid=0x3b3c runnable
"VM Periodic Task Thread" os_prio=2 tid=0x000000001ebe9800 nid=0x4aa0 waiting on condition
JNI global references: 12
Object.wait()情况
class TestTask implements Runnable {
@Override
public void run() {
synchronized (this) {
try {
//等待被唤醒
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class WaitTest {
public static void main(String[] args) throws InterruptedException {
ExecutorService ex = Executors.newFixedThreadPool(1);
ex.execute(new TestTask());
}
}
C:\Users\kpion>jps
13984 DeadLock
18704
24448 Launcher
8992 WaitTest
1076 Jps
18100 EndlessLoop
17324 DemoApplication
5756 JConsole
7196 Main
C:\Users\kpion>jstack -l 8992 > wait.jstack
2020-02-22 15:40:48
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.231-b11 mixed mode):
"DestroyJavaVM" #13 prio=5 os_prio=0 tid=0x00000000034c4800 nid=0x3904 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"pool-1-thread-1" #12 prio=5 os_prio=0 tid=0x000000001fd03000 nid=0x1924 in Object.wait() [0x000000002059f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000076b792658> (a com.kpioneer.demo.TestTask)
at java.lang.Object.wait(Object.java:502)
at com.kpioneer.demo.TestTask.run(WaitTest.java:19)
- locked <0x000000076b792658> (a com.kpioneer.demo.TestTask)
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)
Locked ownable synchronizers:
- <0x000000076b7931b0> (a java.util.concurrent.ThreadPoolExecutor$Worker)
"Service Thread" #11 daemon prio=9 os_prio=0 tid=0x000000001f0e1000 nid=0x3018 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"C1 CompilerThread3" #10 daemon prio=9 os_prio=2 tid=0x000000001f039800 nid=0x480 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"C2 CompilerThread2" #9 daemon prio=9 os_prio=2 tid=0x000000001f034800 nid=0x5cbc waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"C2 CompilerThread1" #8 daemon prio=9 os_prio=2 tid=0x000000001f031000 nid=0x3c0c waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"C2 CompilerThread0" #7 daemon prio=9 os_prio=2 tid=0x000000001f02c000 nid=0x1010 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Monitor Ctrl-Break" #6 daemon prio=5 os_prio=0 tid=0x000000001efda000 nid=0x4a2c runnable [0x000000001f69e000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
- locked <0x000000076b849f08> (a java.io.InputStreamReader)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
- locked <0x000000076b849f08> (a java.io.InputStreamReader)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)
Locked ownable synchronizers:
- None
"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x000000001ee32800 nid=0x5b60 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x000000001eddd000 nid=0x5e98 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x000000001edc1000 nid=0x5fa8 in Object.wait() [0x000000001f39e000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000076b588ed8> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
- locked <0x000000076b588ed8> (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=2 tid=0x000000001edc0800 nid=0x4860 in Object.wait() [0x000000001f29f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000076b586c00> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x000000076b586c00> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
Locked ownable synchronizers:
- None
"VM Thread" os_prio=2 tid=0x000000001cfa9000 nid=0x3914 runnable
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00000000034da800 nid=0x5b20 runnable
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00000000034dc000 nid=0x4b80 runnable
"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00000000034dd800 nid=0x5dac runnable
"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00000000034df000 nid=0x59b8 runnable
"GC task thread#4 (ParallelGC)" os_prio=0 tid=0x00000000034e1800 nid=0x426c runnable
"GC task thread#5 (ParallelGC)" os_prio=0 tid=0x00000000034e3800 nid=0x5d3c runnable
"GC task thread#6 (ParallelGC)" os_prio=0 tid=0x00000000034e7000 nid=0x2424 runnable
"GC task thread#7 (ParallelGC)" os_prio=0 tid=0x00000000034e8000 nid=0x2aec runnable
"VM Periodic Task Thread" os_prio=2 tid=0x000000001f15d000 nid=0x5c64 waiting on condition
JNI global references: 12
等待IO
写个简单的等待用户输入例子:
public class Test {
public static void main(String[] args) throws InterruptedException, IOException {
InputStream is = System.in;
int i = is.read();
System.out.println("exit。");
}
}
内存溢出
4.jmap
jmap命令是一个可以输出所有内存中对象的工具,甚至可以将VM 中的heap,以二进制输出成文本。
打印出某个java进程(使用pid)内存内的,所有‘对象’的情况(如:产生那些对象,及其数量)。
jmap用来查看堆内存使用状况,一般结合jhat使用。
用于显示当前Java堆和永久代的详细信息(如当前使用的收集器,当前的空间使用率等)
-dump:生成java堆转储快照
-heap:显示java堆详细信息(只在Linux/Solaris下有效)
-F:当虚拟机进程对-dump选项没有响应时,可使用这个选项强制生成dump快照(只在Linux/Solaris下有效)
-finalizerinfo:显示在F-Queue中等待Finalizer线程执行finalize方法的对象(只在Linux/Solaris下有效)
-histo:显示堆中对象统计信息
-permstat:以ClassLoader为统计口径显示永久代内存状态(只在Linux/Solaris下有效)
命令格式:jmap [option] vmid
C:\Users\kpion>jmap -heap 17324
Attaching to process ID 17324, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.231-b11
using thread-local object allocation.
Parallel GC with 8 thread(s)
Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 4261412864 (4064.0MB)
NewSize = 88604672 (84.5MB)
MaxNewSize = 1420296192 (1354.5MB)
OldSize = 177733632 (169.5MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
PS Young Generation
Eden Space:
capacity = 125829120 (120.0MB)
used = 112953408 (107.72076416015625MB)
free = 12875712 (12.27923583984375MB)
89.76730346679688% used
From Space:
capacity = 8912896 (8.5MB)
used = 8912896 (8.5MB)
free = 0 (0.0MB)
100.0% used
To Space:
capacity = 16777216 (16.0MB)
used = 0 (0.0MB)
free = 16777216 (16.0MB)
0.0% used
PS Old Generation
capacity = 253231104 (241.5MB)
used = 36305904 (34.62400817871094MB)
free = 216925200 (206.87599182128906MB)
14.337063428037656% used
20840 interned Strings occupying 2194168 bytes.
将数据导出:
jmap -dump:format=b,file=
jmap -dump:format=b,file=heap.bin 17324
C:\Users\kpion>jmap -dump:format=b,file=heap.bin 17324
Dumping heap to C:\Users\kpion\heap.bin ...
Heap dump file created
这个时候会在当前目录以生成一个heap.bin这个二进制文件。
5.jhat
用于分析使用jmap生成的dump文件,是JDK自带的工具,使用方法为:
jhat -J -Xmx512m [file]
C:\Users\kpion>jhat -J-Xmx1024m heap.bin
Reading from heap.bin...
Dump file created Sat Feb 22 15:59:49 CST 2020
Snapshot read, resolving...
Resolving 2760842 objects...
Chasing references, expect 552 dots........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
Eliminating duplicate references........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.
访问 http://localhost:7000/ 查看分析结果
不过jhat没有mat好用,推荐使用mat(Eclipse插件: http://www.eclipse.org/mat ),mat速度更快,而且是图形界面。
MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速、功能丰富的JAVA heap分析工具
使用内存分析工具从众多的对象中进行分析,快速的计算出在内存中对象的占用大小,看看是谁阻止了垃圾收集器的回收工作,并可以通过报表直观的查看到可能造成这种结果的对象。
7.VisualVM的使用
内存溢出
idea VM options配置
-Xms20m -Xmx20m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:\test.hprof
/**
* @date: 2020/2/22 16:16
* @author: xionghu
* @desc: 添加以下参数
* VM Args:-Xms20m -Xmx20m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:\test.hprof
*/
public class HeapOOM {
static class OOMObject {
}
public static void main(String[] args) {
List list = new ArrayList();
while (true) {
list.add(new OOMObject());
}
}
}