笔记:深入理解JVM 第4章 JVM性能监控与故障处理工具

时间:2022-04-02 12:38:48

1、jps   列出JVM 进程

其中: -m  列出输入参数;-l  列出类全名  ;-v  列出JVM 参数

命令: jps -l
输出:

10664  org/netbeans/Main
7164     D:\Install\eclipse\\plugins/org.eclipse.equinox.launcher_1.2.0.v20110502.jar
21124    sun.tools.jps.Jps


命令: jps -l  -m  -v   

10664  org/netbeans/Main --branding visualvm --cachedir C:\Users\Hui\AppData\Local\VisualVM\Cache/7u14 -Xms24m -Xmx256m -XX:MaxPermSize=96m -Dsun.jvmstat.perdata.syncWaitMs=10000 -Dsun.java2d.noddraw=t
rue -Dsun.java2d.d3d=false -Dnetbeans.keyring.no.master=true -Djdk.home=C:\Program Files\Java\jdk1.7.0_45 -Dnetbeans.home=C:\Program Files\Java\jdk1.7.0_45\lib\visualvm\platform -Dnetbeans.user=C:\Use
rs\Hui\AppData\Roaming\VisualVM\7u14 -Dnetbeans.default_userdir_root=C:\Users\Hui\AppData\Roaming\VisualVM -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:\Users\Hui\AppData\Roaming\VisualVM\7u14\v
ar\log\heapdump.hprof -Dnetbeans.system_http_proxy=DIRECT -Dsun.awt.keepWorkingSetOnMinimize=true -Dnetbeans.dirs=C:\Program Files\Java\jdk1.7.0_45\lib\visualvm\visualvm;C:\Program Files\Java\jdk1.7.0
_45\lib\visualvm\profiler
7164    D:\Install\eclipse\\plugins/org.eclipse.equinox.launcher_1.2.0.v20110502.jar -os win32 -ws win32 -arch x86_64 -showsplash -launcher D:\Install\eclipse\eclipse.exe -name Eclipse --launcher.library
 D:\Install\eclipse\\plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.1.100.v20110502\eclipse_1406.dll -startup D:\Install\eclipse\\plugins/org.eclipse.equinox.launcher_1.2.0.v20110502.jar --
launcher.overrideVmargs -exitdata 1b4c_5c -vm C:\Windows\system32\javaw.exe -vmargs -Xms40m -Xmx384m -XX:MaxPermSize=256m -jar D:\Install\eclipse\\plugins/org.eclipse.equinox.launcher_1.2.0.v20110502.

 

2、jstat   列出JVM统计信息

 命令: jstat  -gc  7164  250 20  (获取进程7164的Heap 状况,250毫秒为间隔,共获取20次)

输出:

 S0C    S1C    S0U    S1U      EC       EU        OC         OU       PC     PU    YGC     YGCT    FGC    FGCT     GCT
9216.0 11264.0 4365.6  0.0   63488.0  58064.2   188416.0   121580.2  99328.0 92369.0    228   16.253  80     13.002   29.255
9216.0 11264.0 4365.6  0.0   63488.0  58064.2   188416.0   121580.2  99328.0 92369.0    228   16.253  80     13.002   29.255 
9216.0 11264.0 4365.6  0.0   63488.0  58064.2   188416.0   121580.2  99328.0 92369.0    228   16.253  80     13.002   29.255 ......

其中:

S0C:Survivor0 区的容量

S0U:Survivor0 区的已使用容量

S1C:Survivor1 区的容量

S1U:Survivor1 区的已使用容量

EC:Eden 区的容量

EU:Eden 区的已使用容量

OC:Old 区的容量

OU:Old 区的已使用容量

PC:Perm 区的容量

PU:Perm 区的已使用容量

YGC:Yong GC次数

YGCT:Young GC总耗时

FGC: Full GC次数

FGCT: Full GC总耗时

GCT:   GC总耗时 


命令:  jstat  -class  7164  250 20  ( Class 状况 ) 

Loaded  Bytes  Unloaded  Bytes     Time
 14608 32709.6       10    13.4      48.15
 14608 32709.6       10    13.4      48.15
 14608 32709.6       10    13.4      48.15 

命令: jstat -gccapacity 7164

 NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC      PGCMN    PGCMX     PGC       PC     YGC    FGC
 13824.0 131072.0  82944.0 10752.0 4608.0  61440.0    27648.0   262144.0   188416.0   188416.0  21504.0 262144.0  99328.0  99328.0    229    80

命令: jstat -gcutil 7164
  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT
  0.00  90.85   1.63  64.64  92.99    229   16.280    80   13.002   29.282

命令: jstat -gcnew 7164
 S0C    S1C    S0U    S1U   TT MTT  DSS      EC       EU     YGC     YGCT
10752.0 4608.0    0.0 4186.2 15  15 10752.0  61440.0   1003.6    229   16.280

命令: jstat -gcnewcapacity 7164
  NGCMN      NGCMX       NGC      S0CMX     S0C     S1CMX     S1C       ECMX        EC      YGC   FGC
   13824.0   131072.0    82944.0  43520.0  10752.0  43520.0   4608.0   130048.0    61440.0   229    80

命令: jstat -gcold 7164
   PC       PU        OC          OU       YGC    FGC    FGCT     GCT
 99328.0  92369.0    188416.0    121795.7    229    80   13.002   29.282

命令: jstat -gcoldcapacity 7164
   OGCMN       OGCMX        OGC         OC       YGC   FGC    FGCT     GCT
    27648.0    262144.0    188416.0    188416.0   229    80   13.002   29.282


命令:jstat -gcpermcapacity 7164

  PGCMN      PGCMX       PGC         PC      YGC   FGC    FGCT     GCT
   21504.0   262144.0    99328.0    99328.0   229    80   13.002   29.282

3、jinfo  获取Java配置信息

 主要用于获取隐藏的属性 (jps获取不到的时候)

例子:jps -v -m -l 

输出:

25364 org.apache.zookeeper.server.quorum.QuorumPeerMain /opt/zookeeper-3.3.6/bin/../conf/zoo.cfg -Dzookeeper.log.dir=. -Dzookeeper.root.logger=INFO,CONSOLE -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=false
25196 sun.tools.jps.Jps -m -v -l -Dapplication.home=/opt/jdk1.7.0_40 -Xms8m

从上面输出得不到 MaxHeapSize

命令:jinfo -flag MaxHeapSize 25364

输出:

-XX:MaxHeapSize=4181721088

4、jmap  Java内存映像工具

 命令: jmap -finalizerinfo 25364   (获取等待Finalizer 等待执行 finalize 方法的对象)

Attaching to process ID 25364, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.0-b55
Number of objects pending for finalization: 0


命令: jmap -heap 15968 (获取Heap信息, 如回收器、参数、分布状况等)

输出:

Attaching to process ID 7563, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.0-b55

using parallel threads in the new generation.
using thread-local object allocation.
Concurrent Mark-Sweep GC

Heap Configuration:
   MinHeapFreeRatio = 40
   MaxHeapFreeRatio = 70
   MaxHeapSize      = 3221225472 (3072.0MB)
   NewSize          = 1310720 (1.25MB)
   MaxNewSize       = 17592186044415 MB
   OldSize          = 5439488 (5.1875MB)
   NewRatio         = 7
   SurvivorRatio    = 8
   PermSize         = 21757952 (20.75MB)
   MaxPermSize      = 402653184 (384.0MB)
   G1HeapRegionSize = 0 (0.0MB)

Heap Usage:
New Generation (Eden + 1 Survivor Space):
   capacity = 362414080 (345.625MB)
   used     = 247609248 (236.13858032226562MB)
   free     = 114804832 (109.48641967773438MB)
   68.322193221632% used
Eden Space:
   capacity = 322174976 (307.25MB)
   used     = 236940944 (225.96449279785156MB)
   free     = 85234032 (81.28550720214844MB)
   73.54417991793379% used
From Space:
   capacity = 40239104 (38.375MB)
   used     = 10668304 (10.174087524414062MB)
   free     = 29570800 (28.200912475585938MB)
   26.512280193912865% used
To Space:
   capacity = 40239104 (38.375MB)
   used     = 0 (0.0MB)
   free     = 40239104 (38.375MB)
   0.0% used
concurrent mark-sweep generation:
   capacity = 2818572288 (2688.0MB)
   used     = 622975672 (594.1158981323242MB)
   free     = 2195596616 (2093.884101867676MB)
   22.10252597218468% used
Perm Generation:
   capacity = 161153024 (153.6875MB)
   used     = 160926760 (153.47171783447266MB)
   free     = 226264 (0.21578216552734375MB)
   99.85959680160889% used

93969 interned Strings occupying 9871528 bytes.


命令:jmap -histo 15968 (获取Heap中对象统计信息)

输出:

 num     #instances         #bytes  class name
----------------------------------------------
   1:       1877050      336315944  [C
   2:        905407      178686896  [B
   3:        271119       39064248  <constMethodKlass>
   4:       1612739       38705736  java.lang.String
   5:        271119       34718608  <methodKlass>
   6:        185035       31871016  [I
   7:         27348       31331008  <constantPoolKlass>
   8:        529918       27000872  [Ljava.lang.Object;
   9:        781241       24999712  java.util.HashMap$Entry
  10:        264613       24359256  [Ljava.util.HashMap$Entry;
  11:         26743       19538464  <instanceKlassKlass>
  12:         22397       17551840  <constantPoolCacheKlass>
  13:        579900       13917600  java.util.ArrayList
  14:        171348       13707840  java.lang.reflect.Method
  15:        271239       13019472  java.util.HashMap
  16:        290856       11634240  java.util.LinkedHashMap$Entry
  17:        261992       10479680  java.util.TreeMap$Entry
  18:        391826        9403824  java.lang.Long
  19:        201049        6433568  java.util.concurrent.ConcurrentHashMap$HashEntry
  20:          9347        5358408  <methodDataKlass>
  21:         98130        4710240  com.sun.tools.javac.file.ZipFileIndex$Entry
  22:         40618        4556208  [[B
  23:         70504        3948224  java.util.LinkedHashMap
  24:        116683        3457816  [Ljava.lang.String;
  25:         61713        3455928  org.hibernate.engine.EntityEntry 
.............................

 

 命令:jmap -permstat 15968 (获取持久代中对象统计信息)

输出:
Attaching to process ID 15968, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.0-b55
finding class loader instances ..done.
computing per loader stat ..done.
please wait.. computing liveness..............liveness analysis may be inaccurate ...
class_loader	classes	bytes	parent_loader	alive?	type

<bootstrap>	1199	7151168	  null  	live	<internal>
0x00000000e0108c80	0	0	0x00000000e002e520	live	java/util/ResourceBundle$RBClassLoader@0x00000000db45af08
0x00000000e002e520	743	4624072	0x00000000e002e570	live	sun/misc/Launcher$AppClassLoader@0x00000000db00b988
0x00000000e0033738	1	3024	  null  	dead	sun/reflect/DelegatingClassLoader@0x00000000dae4f480
0x00000000e002e570	0	0	  null  	live	sun/misc/Launcher$ExtClassLoader@0x00000000daf9fed0

total = 5	1943	11778264	    N/A    	alive=4, dead=1	    N/A    

命令:  jmap -dump:file=pib_7563  7563   (生成Heap Dump文件)
输出: 
Dumping heap to /opt/phoenix/bin/pib_7563 ...
Heap dump file created
[admin@VA128 ~]$ ll pib_7563 
-rw------- 1 admin admin 849926091 Dec 23 10:22 pib_7563


5、jhat      Heap Dump 文件分析工具

命令:jhat   pib_15968.bin

输出:

Reading from pid_15968.bin...
Dump file created Tue Dec 23 10:27:40 CST 2014
Snapshot read, resolving...
Resolving 316796 objects...
Chasing references, expect 63 dots...............................................................
Eliminating duplicate references...............................................................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.

在浏览器:http://10.1.20.43:7000/ 可以查看


6、jstack

 生成线程快照。参数 -l 显示锁;-m 显示Native方法;-F 强制。

命令: jstack -l 15968

输出:无锁

2014-12-23 10:32:26
Full thread dump Java HotSpot(TM) 64-Bit Server VM (24.0-b55 mixed mode):

"Attach Listener" daemon prio=10 tid=0x00007f3250001000 nid=0x28d5 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
	- None

"Thread-9" prio=10 tid=0x00007f3298475800 nid=0x3eec runnable [0x00007f327aaaa000]
   java.lang.Thread.State: RUNNABLE
	at java.io.FileInputStream.readBytes(Native Method)
	at java.io.FileInputStream.read(FileInputStream.java:272)
	at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
	at java.io.BufferedInputStream.read(BufferedInputStream.java:254)
	- locked <0x00000000e0008918> (a java.io.BufferedInputStream)
	at com.ph.phoenix.agent.AgentController.getLine(AgentController.java:57)
	at com.ph.phoenix.agent.AgentController.getCommand(AgentController.java:50)
	at com.ph.phoenix.agent.AgentController.run(AgentController.java:102)
	at java.lang.Thread.run(Thread.java:724)

   Locked ownable synchronizers:
	- None

"Thread-8" prio=10 tid=0x00007f329845a800 nid=0x3eeb waiting on condition [0x00007f327abab000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
	at java.lang.Thread.sleep(Native Method)
	at com.ph.phoenix.agent.AgentJobManager.run(AgentJobManager.java:277)
	at java.lang.Thread.run(Thread.java:724)

   Locked ownable synchronizers:
	- None

"Thread-7" daemon prio=10 tid=0x00007f3298458800 nid=0x3eea waiting on condition [0x00007f327acac000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
	at java.lang.Thread.sleep(Native Method)
	at com.ph.phoenix.agent.AgentJobExecutor.rest(AgentJobExecutor.java:123)
	at com.ph.phoenix.agent.AgentJobExecutor.run(AgentJobExecutor.java:144)
	at java.lang.Thread.run(Thread.java:724)

   Locked ownable synchronizers:
	- None
...............................................................................................


 
命令:jstack -l 7563

输出: 有锁

.................................
"Grizzly-kernel-thread(1)" daemon prio=10 tid=0x00007f6658001800 nid=0x1df2 in Object.wait() [0x00007f6699d5c000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at com.sun.grizzly.Controller.waitUntilSelectorHandlersStop(Controller.java:1119)- locked <0x0000000740133438> (a java.util.concurrent.atomic.AtomicInteger)
at com.sun.grizzly.ReadController.start(ReadController.java:121)
at com.sun.grizzly.Controller.run(Controller.java:709)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
  Locked ownable synchronizers:- <0x000000074013b4b0> (a java.util.concurrent.ThreadPoolExecutor$Worker)
 .................................


死锁检测

命令:jstack -l 15436

输出: 有死锁

        - None

"79_A" prio=6 tid=0x000000000a449000 nid=0x1748 waiting for monitor entry [0x000
000000d32f000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at jconsole.DeadLockTest$SyncTask.run(DeadLockTest.java:17)
        - waiting to lock <0x00000000ec900bb8> (a java.lang.Object)
        at java.lang.Thread.run(Unknown Source)

   Locked ownable synchronizers:
        - None

"78_B" prio=6 tid=0x000000000a414000 nid=0x3b24 waiting for monitor entry [0x000
000000c13f000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at jconsole.DeadLockTest$SyncTask.run(DeadLockTest.java:18)
        - waiting to lock <0x00000000ec900bb8> (a java.lang.Object)
        - locked <0x00000000ec9007f0> (a java.lang.Object)
        at java.lang.Thread.run(Unknown Source)

   Locked ownable synchronizers:
        - None

"78_A" prio=6 tid=0x000000000a422800 nid=0x3848 waiting for monitor entry [0x000
000000b86f000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at jconsole.DeadLockTest$SyncTask.run(DeadLockTest.java:18)
        - waiting to lock <0x00000000ec9007f0> (a java.lang.Object)
        - locked <0x00000000ec900bb8> (a java.lang.Object)
        at java.lang.Thread.run(Unknown Source)

   Locked ownable synchronizers:
        - None

"77_B" prio=6 tid=0x000000000a415800 nid=0x780 waiting for monitor entry [0x0000
00000c5bf000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at jconsole.DeadLockTest$SyncTask.run(DeadLockTest.java:17)
        - waiting to lock <0x00000000ec9007f0> (a java.lang.Object)
        at java.lang.Thread.run(Unknown Source)

   Locked ownable synchronizers:
        - None

"77_A" prio=6 tid=0x000000000a41e000 nid=0x315c waiting for monitor entry [0x000
000000b69f000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at jconsole.DeadLockTest$SyncTask.run(DeadLockTest.java:17)
        - waiting to lock <0x00000000ec900bb8> (a java.lang.Object)
        at java.lang.Thread.run(Unknown Source)

   Locked ownable synchronizers:
        - None

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

JNI global references: 107


Found one Java-level deadlock:
=============================
"99_B":
  waiting to lock monitor 0x0000000008684e68 (object 0x00000000ec9007f0, a java.
lang.Object),
  which is held by "78_B"
"78_B":
  waiting to lock monitor 0x000000000a3e34c8 (object 0x00000000ec900bb8, a java.
lang.Object),
  which is held by "78_A"
"78_A":
  waiting to lock monitor 0x0000000008684e68 (object 0x00000000ec9007f0, a java.
lang.Object),
  which is held by "78_B"

Java stack information for the threads listed above:
===================================================
"99_B":
        at jconsole.DeadLockTest$SyncTask.run(DeadLockTest.java:17)
        - waiting to lock <0x00000000ec9007f0> (a java.lang.Object)
        at java.lang.Thread.run(Unknown Source)
"78_B":
        at jconsole.DeadLockTest$SyncTask.run(DeadLockTest.java:18)
        - waiting to lock <0x00000000ec900bb8> (a java.lang.Object)
        - locked <0x00000000ec9007f0> (a java.lang.Object)
        at java.lang.Thread.run(Unknown Source)
"78_A":
        at jconsole.DeadLockTest$SyncTask.run(DeadLockTest.java:18)
        - waiting to lock <0x00000000ec9007f0> (a java.lang.Object)
        - locked <0x00000000ec900bb8> (a java.lang.Object)
        at java.lang.Thread.run(Unknown Source)

Found 1 deadlock.



7、JConsole

 (1). 内存测试

配置:

-Xms100M -Xmx100M -XX:+UseSerialGC


代码:

	static class OOMObject
	{
		public byte[] placeholder = new byte[64*1024];
	}

	public static void main(String[] args) throws InterruptedException {
		List<OOMObject> list = new LinkedList<OOMObject>();
		for(int i=0;i<1000;i++)
		{
			Thread.sleep(50);
			list.add(new OOMObject());
		}
		System.gc();

	}
效果:

可查看总的Heap、非Heap、Eden、Survivor、Tenured、Perm、Code Cache 情况

笔记:深入理解JVM 第4章 JVM性能监控与故障处理工具


(2). 线程测试

代码:

	public static void createBusyThread() {
		Thread t = new Thread(new Runnable() {

			@Override
			public void run() {
				while (true)
					;
			}

		}, " Busy Thread");
		t.start();
	}

	public static void createLockThread(final Object lock) {
		Thread t = new Thread(new Runnable() {

			@Override
			public void run() {
				synchronized (lock) {
					try {
						lock.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}

			}

		}, " Lock Thread");
		t.start();
	}

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		br.readLine();
		createBusyThread();
		br.readLine();
		createLockThread(new Object());
	}

结果:

笔记:深入理解JVM 第4章 JVM性能监控与故障处理工具

 

(3).死锁检测

代码:

          static class SyncTask implements Runnable {
		Object a;
		Object b;

		public SyncTask(Object a, Object b) {
			this.a = a;
			this.b = b;
		}

		@Override
		public void run() {
			synchronized (a) {
				synchronized (b) {
                   System.out.println(Thread.currentThread().getName());
				}
			}
		}

	}

	public static void main(String[] args) {
		Object o1 = new Object();
		Object o2 = new Object();
		for (int i = 0; i < 100; i++) {
			new Thread(new SyncTask(o1, o2), i+"_A").start();
			new Thread(new SyncTask(o2, o1), i+"_B").start();
		}

	}

结果:

笔记:深入理解JVM 第4章 JVM性能监控与故障处理工具

 

8、VisualVM 

 可生成Heap Dump、Thread Dump。可装入Dump 文件进行分析。

 可监控CPU、Heap、Thread 等资源的动态运行情况。