本文记录一下java队的转储和JVisualVM的用法。

示例代码如下:

 1package test.heap;
 2
 3import java.util.ArrayList;
 4import java.util.List;
 5
 6public class TestHeap {
 7    public static void main(String[] args) {
 8        List<TestHeap> list = new ArrayList<>();
 9        while (true) {
10            list.add(new TestHeap());
11            System.gc();
12        }
13    }
14}

启动参数如下图: qidongcanshu 在命令行下执行:jvisualvm,打开这个工具,主界面如下:

  • 左上:CPU使用率,GC状态
  • 右上:堆的总大小,已使用的堆大小
  • 左下:类的监控
  • 右下:线程的监控

这个例子中,在一个死循环中新建对象,同时显示调用gc,运行了2个多小时,发现已使用堆的内存在稳步上升,说明有内存泄漏的趋势。

经测试,如果启动参数-Xmx设置的不管是9m,还是10m,到最后分配的最大堆内存是10m。

点击线程页签,界面如下: 20200202164251 这里线程有5个状态:

  • 运行
  • 休眠
  • 等待
  • 驻留
  • 监视

参考这篇文章Java多线程入门不完全指南顺便复习一下线程的状态。 Thread类定义的线程状态:

  • NEW(新建):线程创建后未启动。
1 /**
2 * Thread state for a thread which has not yet started.
3 */
  • RUNNABLE(可运行):等待系统资源运行的线程。
1 /**
2 * Thread state for a runnable thread.  A thread in the runnable
3 * state is executing in the Java virtual machine but it may
4 * be waiting for other resources from the operating system
5 * such as processor.
6 */
  • BLOCKED(阻塞):当一个线程要进入synchronized语句块/方法时,如果没有获取到锁,会变成BLOCKED。或者在调用Object.wait()后,被notify()唤醒,再次进入synchronized语句块/方法时,如果没有获取到锁,会变成BLOCKED。进入阻塞状态是被动的。
1 /**
2 * Thread state for a thread blocked waiting for a monitor lock.
3 * A thread in the blocked state is waiting for a monitor lock
4 * to enter a synchronized block/method or
5 * reenter a synchronized block/method after calling
6 * {@link Object#wait() Object.wait}.
7 */
  • WAITING(无限等待):等待其它线程执行后,显示唤醒。调用锁对象的wait()方法并未设置时间、其它线程调用join()方法并未设置时间、调用LockSupport.park()方法都会使当前线程进入此状态。进入等待状态是主动的。
 1 /**
 2  * Thread state for a waiting thread.
 3  * A thread is in the waiting state due to calling one of the
 4  * following methods:
 5  * <ul>
 6  *   <li>{@link Object#wait() Object.wait} with no timeout</li>
 7  *   <li>{@link #join() Thread.join} with no timeout</li>
 8  *   <li>{@link LockSupport#park() LockSupport.park}</li>
 9  * </ul>
10  *
11  * <p>A thread in the waiting state is waiting for another thread to
12  * perform a particular action.
13  *
14  * For example, a thread that has called <tt>Object.wait()</tt>
15  * on an object is waiting for another thread to call
16  * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
17  * that object. A thread that has called <tt>Thread.join()</tt>
18  * is waiting for a specified thread to terminate.
19  */
  • TIMED_WAITING(限期等待):等待一段时间后被系统唤醒,不需要显示被唤醒。调用Thread.sleep()方法、调用锁对象的wait()方法并设置时间、其它线程调用join()方法并设置时间、调用LockSupport.parkNanos()方法、调用LockSupport.parkUntil()方法都会使线程进入此状态。
 1/**
 2  * Thread state for a waiting thread with a specified waiting time.
 3  * A thread is in the timed waiting state due to calling one of
 4  * the following methods with a specified positive waiting time:
 5  * <ul>
 6  *   <li>{@link #sleep Thread.sleep}</li>
 7  *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
 8  *   <li>{@link #join(long) Thread.join} with timeout</li>
 9  *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
10  *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
11  * </ul>
12  */
  • TERMINATED(结束):线程run()方法执行结束或异常退出后的线程状态。
1 /**
2  * Thread state for a terminated thread.
3  * The thread has completed execution.
4  */

Thread类和监控工具中的线程状态的对应关系如下

Thread类 VisualVM
RUNNABLE 运行
TIMED_WAITING (sleeping) 休眠
TIMED_WAITING (on object monitor) WAITING (on object monitor) 等待
TIMED_WAITING (parking) WAITING (parking) 驻留
BLOCKED (on object monitor) 监视

点击线程界面的dump按钮可以查看线程具体的内容:

  12020-02-02 17:14:34
  2Full thread dump Java HotSpot(TM) Client VM (25.131-b11 mixed mode, sharing):
  3
  4"RMI TCP Connection(23)-192.168.1.111" #19 daemon prio=5 os_prio=0 tid=0x0536ec00 nid=0x10a0 runnable [0x05c2f000]
  5   java.lang.Thread.State: RUNNABLE
  6        at java.net.SocketInputStream.socketRead0(Native Method)
  7        at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
  8        at java.net.SocketInputStream.read(SocketInputStream.java:171)
  9        at java.net.SocketInputStream.read(SocketInputStream.java:141)
 10        at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
 11        at java.io.BufferedInputStream.read(BufferedInputStream.java:265)
 12        - locked <0x0492f500> (a java.io.BufferedInputStream)
 13        at java.io.FilterInputStream.read(FilterInputStream.java:83)
 14        at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:550)
 15        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
 16        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)
 17        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$3/29995260.run(Unknown Source)
 18        at java.security.AccessController.doPrivileged(Native Method)
 19        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
 20        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
 21        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
 22        at java.lang.Thread.run(Thread.java:748)
 23
 24   Locked ownable synchronizers:
 25        - <0x0492d940> (a java.util.concurrent.ThreadPoolExecutor$Worker)
 26
 27"RMI TCP Connection(idle)" #18 daemon prio=5 os_prio=0 tid=0x0536dc00 nid=0x1f3c waiting on condition [0x00b3f000]
 28   java.lang.Thread.State: TIMED_WAITING (parking)
 29        at sun.misc.Unsafe.park(Native Method)
 30        - parking to wait for  <0x046609d0> (a java.util.concurrent.SynchronousQueue$TransferStack)
 31        at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
 32        at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
 33        at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362)
 34        at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:941)
 35        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1066)
 36        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
 37        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
 38        at java.lang.Thread.run(Thread.java:748)
 39
 40   Locked ownable synchronizers:
 41        - None
 42
 43"RMI TCP Connection(22)-192.168.1.111" #14 daemon prio=5 os_prio=0 tid=0x05528800 nid=0x334 runnable [0x05b8e000]
 44   java.lang.Thread.State: RUNNABLE
 45        at java.net.SocketInputStream.socketRead0(Native Method)
 46        at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
 47        at java.net.SocketInputStream.read(SocketInputStream.java:171)
 48        at java.net.SocketInputStream.read(SocketInputStream.java:141)
 49        at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
 50        at java.io.BufferedInputStream.read(BufferedInputStream.java:265)
 51        - locked <0x04914ea0> (a java.io.BufferedInputStream)
 52        at java.io.FilterInputStream.read(FilterInputStream.java:83)
 53        at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:550)
 54        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
 55        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)
 56        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$3/29995260.run(Unknown Source)
 57        at java.security.AccessController.doPrivileged(Native Method)
 58        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
 59        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
 60        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
 61        at java.lang.Thread.run(Thread.java:748)
 62
 63   Locked ownable synchronizers:
 64        - <0x046e4518> (a java.util.concurrent.ThreadPoolExecutor$Worker)
 65
 66"JMX server connection timeout 13" #13 daemon prio=5 os_prio=0 tid=0x05515800 nid=0xf88 in Object.wait() [0x0573f000]
 67   java.lang.Thread.State: TIMED_WAITING (on object monitor)
 68        at java.lang.Object.wait(Native Method)
 69        - waiting on <0x046d7538> (a [I)
 70        at com.sun.jmx.remote.internal.ServerCommunicatorAdmin$Timeout.run(ServerCommunicatorAdmin.java:168)
 71        - locked <0x046d7538> (a [I)
 72        at java.lang.Thread.run(Thread.java:748)
 73
 74   Locked ownable synchronizers:
 75        - None
 76
 77"RMI Scheduler(0)" #12 daemon prio=5 os_prio=0 tid=0x05513000 nid=0x15a8 waiting on condition [0x056ef000]
 78   java.lang.Thread.State: TIMED_WAITING (parking)
 79        at sun.misc.Unsafe.park(Native Method)
 80        - parking to wait for  <0x046635f8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
 81        at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
 82        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
 83        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
 84        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
 85        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
 86        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
 87        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
 88        at java.lang.Thread.run(Thread.java:748)
 89
 90   Locked ownable synchronizers:
 91        - None
 92
 93"RMI TCP Accept-0" #10 daemon prio=5 os_prio=0 tid=0x054ebc00 nid=0x17cc runnable [0x055ff000]
 94   java.lang.Thread.State: RUNNABLE
 95        at java.net.DualStackPlainSocketImpl.accept0(Native Method)
 96        at java.net.DualStackPlainSocketImpl.socketAccept(DualStackPlainSocketImpl.java:131)
 97        at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)
 98        at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:199)
 99        - locked <0x046871b8> (a java.net.SocksSocketImpl)
100        at java.net.ServerSocket.implAccept(ServerSocket.java:545)
101        at java.net.ServerSocket.accept(ServerSocket.java:513)
102        at sun.management.jmxremote.LocalRMIServerSocketFactory$1.accept(LocalRMIServerSocketFactory.java:52)
103        at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:400)
104        at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:372)
105        at java.lang.Thread.run(Thread.java:748)
106
107   Locked ownable synchronizers:
108        - None
109
110"Service Thread" #8 daemon prio=9 os_prio=0 tid=0x021d5000 nid=0x1e34 runnable [0x00000000]
111   java.lang.Thread.State: RUNNABLE
112
113   Locked ownable synchronizers:
114        - None
115
116"C1 CompilerThread0" #7 daemon prio=9 os_prio=2 tid=0x021d0800 nid=0xc6c waiting on condition [0x00000000]
117   java.lang.Thread.State: RUNNABLE
118
119   Locked ownable synchronizers:
120        - None
121
122"Monitor Ctrl-Break" #6 daemon prio=5 os_prio=0 tid=0x021d6000 nid=0x1acc runnable [0x0529f000]
123   java.lang.Thread.State: RUNNABLE
124        at java.net.SocketInputStream.socketRead0(Native Method)
125        at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
126        at java.net.SocketInputStream.read(SocketInputStream.java:171)
127        at java.net.SocketInputStream.read(SocketInputStream.java:141)
128        at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
129        at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
130        at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
131        - locked <0x045db0d8> (a java.io.InputStreamReader)
132        at java.io.InputStreamReader.read(InputStreamReader.java:184)
133        at java.io.BufferedReader.fill(BufferedReader.java:161)
134        at java.io.BufferedReader.readLine(BufferedReader.java:324)
135        - locked <0x045db0d8> (a java.io.InputStreamReader)
136        at java.io.BufferedReader.readLine(BufferedReader.java:389)
137        at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)
138
139   Locked ownable synchronizers:
140        - None
141
142"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x0218f000 nid=0x1ecc waiting on condition [0x00000000]
143   java.lang.Thread.State: RUNNABLE
144
145   Locked ownable synchronizers:
146        - None
147
148"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x0218d000 nid=0x10a4 runnable [0x00000000]
149   java.lang.Thread.State: RUNNABLE
150
151   Locked ownable synchronizers:
152        - None
153
154"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x02174000 nid=0xa04 in Object.wait() [0x0514f000]
155   java.lang.Thread.State: WAITING (on object monitor)
156        at java.lang.Object.wait(Native Method)
157        - waiting on <0x04557948> (a java.lang.ref.ReferenceQueue$Lock)
158        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
159        - locked <0x04557948> (a java.lang.ref.ReferenceQueue$Lock)
160        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
161        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)
162
163   Locked ownable synchronizers:
164        - None
165
166"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x02117000 nid=0x13c8 in Object.wait() [0x050ff000]
167   java.lang.Thread.State: WAITING (on object monitor)
168        at java.lang.Object.wait(Native Method)
169        - waiting on <0x04556380> (a java.lang.ref.Reference$Lock)
170        at java.lang.Object.wait(Object.java:502)
171        at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
172        - locked <0x04556380> (a java.lang.ref.Reference$Lock)
173        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
174
175   Locked ownable synchronizers:
176        - None
177
178"main" #1 prio=5 os_prio=0 tid=0x00e7c800 nid=0x1d48 runnable [0x00bbf000]
179   java.lang.Thread.State: RUNNABLE
180        at java.lang.Runtime.gc(Native Method)
181        at java.lang.System.gc(System.java:993)
182        at test.heap.TestHeap.main(TestHeap.java:11)
183
184   Locked ownable synchronizers:
185        - None
186
187"VM Thread" os_prio=2 tid=0x02112c00 nid=0x1d04 runnable 
188
189"VM Periodic Task Thread" os_prio=2 tid=0x053b3400 nid=0x14f8 waiting on condition 
190
191JNI global references: 237