JVM performance tuning monitoring tools jps, jstack, jmap, jhat, jstat

JDK itself provides many convenient JVM performance tuning and monitoring tools. In addition to the integrated VisualVM and jConsole, there are also small tools such as jps, jstack, jmap, jhat, and jstat. Can start to understand the common tools for JVM performance tuning.

    In real enterprise Java development, sometimes we will encounter the following problems:

1. OutOfMemoryError, insufficient memory

2. Memory leak

3. Thread deadlock

4. Lock contention (Lock Contention)

5. The Java process consumes too much CPU

    These problems may be overlooked by many people in daily development (for example, some people just restart the server or increase the memory when encountering the above problems, but will not get to the root of the problem), but it is an advanced Java programmer to understand and solve these problems. necessary requirements. This article will introduce some commonly used JVM performance tuning and monitoring tools, hoping to be useful. This article refers to a lot of information on the Internet, and it is difficult to list them one by one. I would like to express my gratitude to the authors of these materials! For information about JVM performance tuning, please refer to the end of this article.

A、 jps(Java Virtual Machine Process Status Tool)      

    jps is mainly used to output process status information running in the JVM. The syntax format is as follows:

jps [options] [hostid]

    If no hostid is specified, it defaults to the current host or server.

    The command line parameter options are described as follows:

-q Do not output the class name, Jar name and parameters passed into the main method 
-m Output the parameters passed into the main method 
-l Output the full name of the main class or Jar 
-v Output the parameters passed into the JVM

   For example:

root@ubuntu:/# jps -m -l
2458 org.artifactory.standalone.main.Main /usr/local/artifactory-2.2.5/etc/jetty.xml
29920 com.sun.tools.hat.Main -port 9998 /tmp/dump.dat
3149 org.apache.catalina.startup.Bootstrap start
30972 sun.tools.jps.Jps -m -l
8247 org.apache.catalina.startup.Bootstrap start
25687 com.sun.tools.hat.Main -port 9999 dump.dat
21711 mrf-center.jar

B、  ​​jstack

    jstack is mainly used to view the thread stack information in a Java process. The syntax format is as follows:

jstack [option] pid
jstack [option] executable core
jstack [option] [server-id@]remote-hostname-or-ip

    The command line parameter options are described as follows:

-l long listings, will print out additional lock information, you can use jstack -l pid to observe the lock holding situation when a deadlock occurs 
-m mixed mode, not only output Java stack information, but also output C/C++ stack information (such as Native method)

    jstack can locate the thread stack, and we can locate the specific code according to the stack information, so it is used a lot in JVM performance tuning. Let's take an example to find out the most CPU-consuming Java thread in a Java process and locate the stack information. The commands used are ps, top, printf, jstack, and grep.

    The first step is to find out the Java process ID. The name of the Java application I deployed on the server is mrf-center:

root@ubuntu:/# ps -ef | grep mrf-center | grep -v grep
root     21711     1  1 14:47 pts/3    00:02:10 java -jar mrf-center.jar

    The process ID is 21711. The second step is to find the most CPU-consuming thread in the process. You can use ps -Lfp pid or ps -mp pid -o THREAD, tid, time or top -Hp pid. I use the third one here , the output is as follows:

    The TIME column is the CPU time consumed by each Java thread. The thread with the longest CPU time is the thread whose thread ID is 21742. Use

printf "%x\n" 21742

 

    The hexadecimal value of 21742 is 54ee, which will be used below.    

    OK, the next step is finally jstack's turn. It is used to output the stack information of process 21711, and then grep according to the hexadecimal value of the thread ID, as follows:

root@ubuntu:/# jstack 21711 | grep 54ee
"PollIntervalRetrySchedulerThread" prio=10 tid=0x00007f950043e000 nid=0x54ee in Object.wait() [0x00007f94c6eda000]

    You can see that the CPU is consumed in the Object.wait() of the PollIntervalRetrySchedulerThread class. I found my code and located the following code:

// Idle wait
getLog().info("Thread [" + getName() + "] is idle waiting...");
schedulerThreadState = PollTaskSchedulerThreadState.IdleWaiting;
long now = System.currentTimeMillis();
long waitTime = now + getIdleWaitTime();
long timeUntilContinue = waitTime - now;
synchronized(sigLock) {
    try {
        if(!halted.get()) {
            sigLock.wait(timeUntilContinue);
        }
    } 
    catch (InterruptedException ignore) {
    }
}

    It is the idle waiting code of the polling task. The above sigLock.wait(timeUntilContinue) corresponds to the previous Object.wait().

C、 jmap(Memory Map)和jhat(Java Heap Analysis Tool)

    jmap is used to view the heap memory usage, usually combined with jhat.

    The jmap syntax format is as follows:

jmap [option] pid
jmap [option] executable core
jmap [option] [server-id@]remote-hostname-or-ip

    If running on a 64-bit JVM, you may need to specify the -J-d64 command option parameter.

jmap -permstat pid

    Print the class loader of the process and the persistent generation object information loaded by the class loader, output: class loader name, whether the object is alive (unreliable), object address, parent class loader, loaded class size and other information, as shown in the figure below :

   Use jmap -heap pid to view process heap memory usage, including the GC algorithm used, heap configuration parameters, and heap memory usage in each generation. Like the following example:

root@ubuntu:/# jmap -heap 21711
Attaching to process ID 21711, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 20.10-b01

using thread-local object allocation. Parallel GC with 4 thread(s)

Heap Configuration:    MinHeapFreeRatio = 40    MaxHeapFreeRatio = 70    MaxHeapSize      = 2067791872 (1972.0MB)    NewSize          = 1310720 (1.25MB)    MaxNewSize       = 17592186044415 MB    OldSize          = 5439488 (5.1875MB)    NewRatio         = 2    SurvivorRatio    = 8    PermSize         = 21757952 (20.75MB)    MaxPermSize      = 85983232 (82.0MB)

Heap Usage: PS Young Generation Eden Space:    capacity = 6422528 (6.125MB)    used     = 5445552 (5.1932830810546875MB)    free     = 976976 (0.9317169189453125MB)    84.78829520089286% used From Space:    capacity = 131072 (0.125MB)    used     = 98304 (0.09375MB)    free     = 32768 (0.03125MB)    75.0% used To Space:    capacity = 131072 (0.125MB)    used     = 0 (0.0MB)    free     = 131072 (0.125MB)    0.0% used PS Old Generation    capacity = 35258368 (33.625MB)    used     = 4119544 (3.9287033081054688MB)    free     = 31138824 (29.69629669189453MB)    11.683876009235595% used PS Perm Generation    capacity = 52428800 (50.0MB)    used     = 26075168 (24.867218017578125MB)    free     = 26353632 (25.132781982421875MB)    49.73443603515625% used    ....</pre>

    Use jmap -histo[:live] pid to view the histogram of the number and size of objects in the heap memory. If you bring live, only live objects are counted, as follows:

root@ubuntu:/# jmap -histo:live 21711 | more

 num     #instances         #bytes  class name

   1:         38445        5597736  <constMethodKlass>    2:         38445        5237288  <methodKlass>    3:          3500        3749504  <constantPoolKlass>    4:         60858        3242600  <symbolKlass>    5:          3500        2715264  <instanceKlassKlass>    6:          2796        2131424  <constantPoolCacheKlass>    7:          5543        1317400  [I    8:         13714        1010768  [C    9:          4752        1003344  [B   10:          1225         639656  <methodDataKlass>   11:         14194         454208  java.lang.String   12:          3809         396136  java.lang.Class   13:          4979         311952  [S   14:          5598         287064  [[I   15:          3028         266464  java.lang.reflect.Method   16:           280         163520  <objArrayKlassKlass>   17:          4355         139360  java.util.HashMap$Entry   18:          1869         138568  [Ljava.util.HashMap$Entry;   19:          2443          97720  java.util.LinkedHashMap$Entry   20:          2072          82880  java.lang.ref.SoftReference   21:          1807          71528  [Ljava.lang.Object;   22:          2206          70592  java.lang.ref.WeakReference   23:           934          52304  java.util.LinkedHashMap   24:           871          48776  java.beans.MethodDescriptor   25:          1442          46144  java.util.concurrent.ConcurrentHashMap$HashEntry   26:           804          38592  java.util.HashMap   27:           948          37920  java.util.concurrent.ConcurrentHashMap$Segment   28:          1621          35696  [Ljava.lang.Class;   29:          1313          34880  [Ljava.lang.String;   30:1396 33504 java.util.LinkedList$Entry 31: 462 33264 java.lang.reflect.Field 32: 1024 32768 java.util.Hashtable$Entry 33: 948 31440 [Ljava.util.concurrent.ConcurrentHashMap$HashEntry</pre>;

    class name is the object type, described as follows:

B byte 
C char 
D double 
F float 
I int 
J long 
Z boolean 
[ array, such as [I means int[] 
[L+ class name other objects

    Another very common situation is: use jmap to dump the process memory usage into a file, and then use jhat to analyze and view it. The format of jmap dump command is as follows:

jmap -dump:format=b,file=dumpFileName

    I also performed Dump on the above process ID 21711:

root@ubuntu:/# jmap -dump:format=b,file=/tmp/dump.dat 21711     
Dumping heap to /tmp/dump.dat ...
Heap dump file created

   The dumped files can be viewed with tools such as MAT, VisualVM, etc. Here, use jhat to view:

root@ubuntu:/# jhat -port 9998 /tmp/dump.dat
Reading from /tmp/dump.dat...
Dump file created Tue Jan 28 17:46:14 CST 2014
Snapshot read, resolving...
Resolving 132207 objects...
Chasing references, expect 26 dots..........................
Eliminating duplicate references..........................
Snapshot resolved.
Started HTTP server on port 9998
Server is ready.

     Then you can enter the host address: 9998 in the browser to view:

    You can explore the part in the red line above by yourself. The last item supports OQL (Object Query Language).

D. jstat (JVM statistical monitoring tool)

    The syntax format is as follows:

jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]

    vmid is the virtual machine ID, which is generally the process ID on Linux/Unix systems. interval is the sampling interval. count is the number of samples. For example, the following output is GC information, the sampling interval is 250ms, and the sampling number is 4:

root@ubuntu:/# jstat -gc 21711 250 4 
 S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT    
192.0 192.0 64.0 0.0 6144.0 1854.9 32000.0 4111.6 55296.0 25472.7 702 0 .431 3 0.218 0.649 192.0 192.0 
64.0 0.0 6144.0 1972.2 32000.0 4111.6 55296.0 25472.7 702 0.431 3 0.218 0.649 
192.0 192.0 64.0 0.0 6144.0 1972.2 32000.0 4111.6 55296.0 25472.7 702 0.431 3 0.2 18 0.649 192.0 192.0 64.0 0.0 6144.0 2109.7 32000.0 4111.6 55296.0 25472.7 702 0.431 3 0.218 
0.649

    To understand the meaning of the above columns, first look at the JVM heap memory layout:

    As can be seen:

Heap memory = young generation + old generation + permanent generation 
Young generation = Eden area + two Survivor areas (From and To)

    Now to explain the meaning of each column:

S0C, S1C, S0U, S1U: Survivor 0/1 area capacity (Capacity) and usage (Used) 
EC, EU: Eden area capacity and usage 
OC, OU: Old generation capacity and usage 
PC, PU: Permanent generation Capacity and usage 
YGC, YGT: Young generation GC times and GC time-consuming 
FGC, FGCT: Full GC times and Full GC time-consuming 
GCT: Total GC time-consuming

Other JVM performance tuning reference materials:

"Java Virtual Machine Specification"

《Java Performance》

《Trouble Shooting Guide for JavaSE 6 with HotSpot VM》: http://www.oracle.com/technetwork/java/javase/tsg-vm-149989.pdf 

《Effective Java》

VisualVM: http://docs.oracle.com/javase/7/docs/technotes/guides/visualvm/

jConsole:  http://docs.oracle.com/javase/1.5.0/docs/guide/management/jconsole.html

Monitoring and Managing JavaSE 6 Applications: http://www.oracle.com/technetwork/articles/javase/monitoring-141801.html

From: http://my.oschina.net/feichexia/blog/196575

Guess you like

Origin blog.csdn.net/weixin_43167662/article/details/130429993