Original address: http://www.javatang.com
A period of time on-line after the system upgrade, there is a serious high CPU problem, so began a series of optimization processing, now the process into a series of articles.
Basic concepts
When analyzing a Java memory leak, you need a dump file that records the memory footprint, thread execution, and so on during the runtime of the JVM, typically with thread dump and heap dump.
- Thread dump is a text file that mainly records the situation that the JVM executes at a certain point in time, in the form of a stack. The thread dump file can be used to analyze where the problem of the program appears, thus locating the specific code and then correcting it. Thread dump needs to be parsed in conjunction with the threading ID of the system resources to make sense.
- Heap dump primarily records the use of objects in the JVM heap at some point in time, a snapshot of the JVM heap at some point, a binary file that is used primarily to analyze which objects are taking up too much of the heap space to find the object that caused the memory leak.
Both of the above dump files are real-time, so they need to be generated when the server is having problems, and generate several files to facilitate comparative analysis. Let's take a look at how to generate thread dump first.
generate thread dump using Jstack
When the server appears high CPU, first execute the top -c
command to dynamically display the process and occupy the resources of the ranking, such as:
The parameters in the back of top -c
can display detailed information about the process. top
You can also perform some shortcut keys when the command executes:
1
For multi-core servers, you can show how each CPU consumes resources
shift+h
Show All thread information
shift+w
Save the top
settings of the current command to a ~/.toprc
file so that you don't have to execute the shortcut key every time.
For example, the PID 1503 process consumes a lot of CPU resources, the next need to take the highest CPU process of the thread print out, you can use top -bn1 -H -p <pid>
the command, the results are as follows:
-bn1
the meaning of the above parameter is to output only one result at a time, instead of displaying a dynamic result.
I personally prefer to use the command to view the following sort ps -mp <pid> -o THREAD,tid,time | sort -k2r
parameters according to the CPU scale consumed by the thread, the result is as follows:
Next we know the protagonist of today jstack
, this is a built-in tool that starts in JDK5 to print the state of the thread running in the specified process, including the number of threads, the existence of deadlocks, resource contention, and the state of the thread. There are a couple of common parameters:
-l
long list, print additional information about the lock
-m
Print all stack information for Java and JNI frameworks
Because the thread ID is displayed as a 16 binary in the stack information, you need to use a printf "%x \n" <tid>
command to turn the field ID into a 16-based value, and then execute jstack -l <pid> | grep <thread-hex-id> -A 10
the command to display the stack information for the error, such as:
The parameters in the command above -A 10
are used to specify the number of rows to display, otherwise only one line of information is displayed.
By doing so, you can quickly locate the code for the program problem, and then analyze and improve the code. Note: Multiple Thread dump information needs to be presented in multiple time periods, and then a comprehensive comparative analysis is made, and it makes no sense to analyze a file separately.
Generate shell Files
The entire analysis process is described above, but all the commands are real-time, so it's best to create a shell script to do it in an instant, and the shell that is provided in this article when the CPU is high is improved as follows:
#!/bin/bashif [$#-ne 1]; Then echo "Usage: $ <pid> [Line-number]" exit 1fi# java homeif test-z $JAVA _home then java_home= '/usr /local/jdk ' fi#pidpid=$1# checking pidif test-z "$ ($JAVA _home/bin/jps-l | Cut-d '-F 1 | grep $pid) "Then echo" process of $pid was not exists " exitfi#line numberif test-z $linenumthen linenum=10fist ackfile=stack$pid.dumpthreadsfile=threads$pid.dump# generate Java stack$java_home/bin/jstack-l $pid >> $ STACKFILEPS-MP $pid-O thread,tid,time | SORT-K2R | awk ' {if ($ = "USER" && $ = "0.0" && $8! = "-") print $8;} ' | Xargs printf "%x\n" >> $threadsfiletids = "$ (cat $threadsfile)" For Tid in $tidsdo echo "----------------------- -------ThreadId ($tid)------------------------------" cat $stackfile | grep 0x$tid-a $linenumdonerm-F $stackfile $ Threadsfile
The next article will tell you how to analyze the files generated by Jstack
One of the Java Memory Leak Analysis series: locating thread stack information using Jstack