preface
In real enterprise Java development, we sometimes encounter the following problems:
1.OutOfMemoryError, insufficient memory
2. Memory leaks
3. The thread deadlocks
Key Contention for Lock Contention
5.Java processes consume too much CPU
.
These problems may be ignored by many people in daily development (for example, some people just restart the server or increase the memory without getting to the root of the problem), but being able to understand and solve these problems is a prerequisite for Java programmers to advance. This article will introduce some of the most commonly used JVM performance tuning monitoring tools in the hope of providing some inspiration. This article referred to a lot of information on the Internet, it is difficult to list one by one, here to express gratitude to the author of these information! For information on JVM performance tuning, see the end of this article.
A, JPS (Java Virtual Machine Process Status Tool)
JPS is mainly used to output information about the status of processes running in the JVM. The syntax is as follows:
jps [options] [hostid]
Copy the code
If you do not specify hostid, the default value is the current host or server.
The command line parameters are described as follows:
-q Does not output the class name, Jar name, or parameters passed to main. -m Outputs the parameters passed to main. -l Outputs the full name of the main class or JarCopy the code
For example:
Root @ ubuntu: / # JPS - m - l 2458 org. Artifactory. Standalone. Main. The main/usr/local/artifactory -- 2.2.5 / etc/jetty. The 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.jarCopy the code
B、 jstack
Jstack is used to view stack information about threads in a Java process. The syntax is as follows:
Jstack [option] pid jstack [option] Executable core jstack [option] [server-id@]remote-hostname-or- IP The command line parameters are described as follows:
Listing: -l long listings will display additional lock information in the event of a deadlock using jstack -l PID to keep track of lock holdings -m mixed mode will display Java stack information. Jstack also outputs C/C++ stack information (such as Native methods). Jstack can locate the thread stack, and from the stack information we can locate specific code, so it is used a lot in JVM performance tuning. Here is an example to find the most cpu-consuming Java thread in a Java process and locate the stack information using the commands ps, top, printf, jstack, and grep.
The first step is to find the Java process ID. The name of the Java application I have 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 Ps-lfp pid or ps-mp pid -o THREAD, tid, time, or top-HP PID.
The TIME column is the CPU TIME consumed by each Java thread. The longest CPU TIME is used by the thread whose ID is 21742
printf "%x\n" 21742
Copy the code
We get 21742 with a hex value of 54ee, which we’ll use next.
Jstack is used to output the stack information for process 21711, and grep from 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]
Copy the code
Can see CPU consumption in PollIntervalRetrySchedulerThread Object of this class. The wait (), I was looking for under my code, orientation to 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) { } }Copy the code
It is the idle wait code for the polling task, and siglock. wait(timeUntilContinue) corresponds to object.wait ().
C, JMAP (Memory Map), and JHAT (Java Heap Analysis Tool)
Jmap is used to check heap memory usage, usually in combination with JHAT.
Jmap syntax is as follows:
jmap [option] pid
jmap [option] executable core
jmap [option] [server-id@]remote-hostname-or-ip
Copy the code
If you are running on a 64-bit JVM, you may need to specify the -j-d64 command option parameter.
jmap -permstat pid
Copy the code
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 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. Take 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 Ththread -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%, informs the 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.13278198242421875 MB) 49.73443603515625%, informs...Copy the code
Jmap-histo [:live] pid = jmap-histo [:live] pid = jmap-histo [:live] pid
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;
Copy the code
Class name is an object type, described as follows:
B byte C char D double F float I int J long Z Boolean [array, e.g. [I denotes int[] [L+ class name other objectCopy the code
Another common scenario is to dump the process memory usage into a file using Jmap and then analyze it using JHAT. The jmap dump command is in the following format:
jmap -dump:format=b,file=dumpFileName pid
Copy the code
Dump (ID: 21711);
root@ubuntu:/# jmap -dump:format=b,file=/tmp/dump.dat 21711
Dumping heap to /tmp/dump.dat ...
Heap dump file created
Copy the code
Dump files can be viewed with MAT, VisualVM and other tools, here using 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.
Copy the code
Jhat -j -xmx512m -port 9998 / TMP /dump.dat if the Dump file is too large, you may need to add -j -xmx512m to specify maximum heap memory. Then you can enter the host address :9998 in the browser to view:
The last item supports OQL (Object Query Language).
**D, **jstat (JVM Statistics Monitoring Tool)
The syntax is as follows:
jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]
Copy the code
The vmID is the ID of a Java VIRTUAL machine (VM). On Linux/Unix, it is generally the ID of a process. Interval is the sampling interval. Count is the number of samples. For example, the following output is GC information, sampling interval is 250ms, 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.218 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 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.649Copy the code
To see what the above columns mean, look at the JVM heap memory layout:
As can be seen:
Heap memory = Young generation + Old generation + Permanent generation Young generation = Eden region + two Survivor regions (From and To)Copy the code
Now explain the meaning of each column:
S0C, S1C, S0U, and S1U: Survivor 0/1 Capacity and usage EC, EU: Eden Capacity and usage OC, OU: Capacity and usage of the elderly generation PC, PU: Capacity and usage of the permanent generation YGC, YGT: Young GC count and GC duration FGC and FGCT: Full GC count and Full GC duration GCT: total GC durationCopy the code
**E, ** Hprof (Heap/CPU Profiling Tool)
Hprof is able to show CPU usage and statistics on heap memory usage.
The syntax is as follows:
java -agentlib:hprof[=options] ToBeProfiledClass
java -Xrunprof[:options] ToBeProfiledClass
javac -J-agentlib:hprof[=options] ToBeProfiledClass
Copy the code
The full command options are as follows:
Option Name and Value Description Default --------------------- ----------- ------- heap=dump|sites|all heap profiling all cpu=samples|times|old CPU usage off monitor=y|n monitor contention n format=a|b text(txt) or binary output a file=<file> write data to file java.hprof[.txt] net=<host>:<port> send data over a socket off depth=<size> stack trace The depth interval = 4 > < ms sample interval in 10 ms cutoff = < value > output cutoff point 0.0001 lineno = y | n line number in traces? y thread=y|n thread in traces? n doe=y|n dump on exit? y msa=y|n Solaris micro state accounting n force=y|n force output to <file> y verbose=y|n print messages about dumps yCopy the code
Here are some examples from the official guide.
Sample CPU Usage Sampling Profiling(CPU =samples) :
java -agentlib:hprof=cpu=samples,interval=20,depth=3 Hello
Copy the code
Sample CPU consumption every 20 milliseconds, stack depth 3, and generate a profile named java.hprofe.txt in the current directory.
Example of CPU Usage Times Profiling(CPU = Times), which can obtain more fine-grained CPU consumption information than the CPU Usage Sampling Profile, down to the beginning and end of each method call, It is implemented using bytecode injection (BCI) :
javac -J-agentlib:hprof=cpu=times Hello.java
Copy the code
Example of Heap Allocation Profiling(Heap = Sites) :
javac -J-agentlib:hprof=heap=sites Hello.java
Copy the code
An example of Heap Dump(Heap = Dump), which generates more detailed Heap Dump information than the above Heap Allocation Profiling:
javac -J-agentlib:hprof=heap=dump Hello.java
Copy the code
Although adding the -xrunprof :heap=sites parameter to the JVM startup parameter can generate a CPU/ heap Profile, it has a significant impact on JVM performance and is not recommended for online server environments.
The last
I here organized a: JVM related data material documentation, JVM brain map, Spring family barrel series, Java systematic information, (including Java core knowledge, interview topics and the latest 20 years of the Internet, e-books, etc.) friends who need to pay attention to the public number [procedure Yuan Small wan] can be obtained.