VisualVM is a free, integrated visualization tool that integrates multiple JDK command-line tools to provide you with powerful analytical capabilities for performance analysis and tuning of Java applications. These features include generating and analyzing massive amounts of data, tracking memory leaks, monitoring the garbage collector, performing memory and CPU analysis, and it also supports browsing and manipulation on MBeans. This article mainly describes how to use VisualVM for performance analysis and tuning.
Directory: Preparatory work
Memory Analysis Chapter memory heap heap Persistent zone PermGen CPU Analysis Thread analysis article reference
Preparatory work
Since JDK 6 Update 7 has been part of the Oracle JDK, it is located under the Bin folder of the JDK root directory, without the need to install and run directly.
Memory Analysis Chapter
VisualVM helps us analyze memory usage by detecting class and object information loaded in the JVM, and we can perform memory analysis of the application through the VisualVM Monitoring tab.
1) Memory heap Heap
First we look at the memory heap heap usage, and the process of my native eclipse is shown in VISUALVM as follows:
Write a small program that takes up a lot of memory and runs it.
The procedure is as follows:
PackageJVISUALVM; Public classJavaheaptest { Public Final Static intOUTOFMEMORY = 200000000; PrivateString Oom; Private intlength; StringBuffer Tempoom=NewStringBuffer (); PublicJavaheaptest (intLeng) { This. length =Leng; inti = 0; while(I <Leng) {i++; Try{tempoom.append (A); } Catch(OutOfMemoryError e) {e.printstacktrace (); Break; } } This. Oom =tempoom.tostring (); } PublicString Getoom () {returnOom; } Public intGetLength () {returnlength; } Public Static voidMain (string[] args) {javaheaptest javaheaptest=Newjavaheaptest (OUTOFMEMORY); System.out.println (Javaheaptest.getoom (). Length ()); }}
View VISUALVM Monitor tab, heap memory is getting bigger
Before the program runs, click the heap Dump button, wait for a moment, get the Dump result, you can see some summary information
Click Classes to find that char[] occupies the largest amount of memory
Double-click it to get the following instances results
Instances are arranged by size from large to small
The first one is the largest, expand the values of the field area
StringBuffer types of global variables tempoom occupy a large amount of memory, note that local variables can not be through heap dump to obtain the results of the analysis.
In addition, for "Heap dump", in the remote monitoring of the JVM, VISUALVM is not this function, only local monitoring.
# # #转载注明出处: http://www.cnblogs.com/wade-xu/p/4369094.html
2) permanently reserved area PermGen
Second, consider the use of permanent reserved areas PermGen
Run a class-loaded program with the following code:
PackageJVISUALVM;ImportJava.io.File;ImportJava.lang.reflect.Method;Importjava.net.MalformedURLException;ImportJava.net.URL;ImportJava.net.URLClassLoader;Importjava.util.ArrayList;Importjava.util.List; Public classTestpermgen {Private StaticList<object> inslist =NewArraylist<object>(); Public Static voidMain (string[] args)throwsException {permleak (); } Private Static voidPermleak ()throwsException { for(inti = 0; i < 1000; i++) {url[] URLs=Geturls (); URLClassLoader URLClassLoader=NewURLClassLoader (URLs,NULL); Class<?> Logfclass = Class.forName ("Org.apache.commons.logging.LogFactory",true, URLClassLoader); Method GetLog= Logfclass.getmethod ("GetLog", String.class); Object result= Getlog.invoke (Logfclass, "Testpermgen"); Inslist.add (result); System.out.println (i+ ": " +result); } } Private StaticUrl[] Geturls ()throwsmalformedurlexception {File Libdir=NewFile ("c:/users/wadexu/.m2/repository/commons-logging/commons-logging/1.1.1"); File[] Subfiles=Libdir.listfiles (); intCount =subfiles.length; Url[] URLs=NewUrl[count]; for(inti = 0; I < count; i++) {Urls[i]=Subfiles[i].touri (). Tourl (); } returnURLs; } }
After a type is loaded, a corresponding Java.lang.Class instance is created, and the instance itself is stored in the heap like a normal object instance, which I think is a special instance, in part because it acts as a proxy for accessing type information in the PermGen region.
After running for a period of time to throw OutOfMemoryError, VISUALVM monitoring results are as follows:
Conclusion: The heap space of PermGen region allocation is too small, we can solve it by setting-xx:permsize parameter and-xx:maxpermsize parameter.
For an in-depth analysis of PermGen Oom, please refer to this article
For perform GC, please refer to this article
This part of the knowledge is still more in-depth, have time to continue to study.
# # #转载注明出处: http://www.cnblogs.com/wade-xu/p/4369094.html
CPU Analysis Chapter
The main purpose of CPU performance analysis is to count the function's invocation and execution time, or, more simply, to count the application's CPU usage.
CPU usage when no program is running such as:
Run a CPU-intensive applet with the following code
PackageJVISUALVM; Public classMemorycputest { Public Static voidMain (string[] args)throwsinterruptedexception {cpufix (); } /*** CPU runs a fixed percentage * *@throwsinterruptedexception*/ Public Static voidCpufix ()throwsinterruptedexception {//80% of the share intBusyTime = 8; //20% of the share intIdeltime = 2; //Start Time LongStartTime = 0; while(true) { //Start TimeStartTime =System.currenttimemillis (); /** Run Time*/ while(System.currenttimemillis ()-StartTime <busyTime) { ; } //Rest TimeThread.Sleep (ideltime); } }}
View Monitoring page Monitor tab
Excessive CPU utilization may be due to inefficient code in our projects;
When we put pressure on the program, too low CPU utilization could be a problem with the program.
Click on the Sampler sampler, click on the "CPU" button to start the CPU profiling session, VisualVM will detect all the methods that are called by the application,
In the CPU Samples tab can see our Method Cpufix () for the longest time, such as:
Switch to the Thread CPU time page, our main function this process consumes the longest CPU, such as:
# # #转载注明出处: http://www.cnblogs.com/wade-xu/p/4369094.html
Threading Analysis Chapter
The Java language enables multithreaded applications to be implemented very well. When we debug a multithreaded application or develop performance tuning later on, we often need to know the running state of all the threads in the current program, whether there are deadlocks, Jes, and so on, so as to analyze the possible problems of the system.
Within the VisualVM monitoring tab, we can view real-time information such as the number of active threads (live threads) and daemon threads (Daemon threads) in the current application.
Run a small program with the following code:
PackageJVISUALVM; Public classMyThreadextendsthread{ Public Static voidMain (string[] args) {MyThread mt1=NewMyThread ("Thread a"); MyThread mt2=NewMyThread ("Thread B"); Mt1.setname ("My-thread-1"); Mt2.setname ("My-thread-2"); Mt1.start (); Mt2.start (); } PublicMyThread (String name) {} Public voidrun () { while(true) { } } }
Live threads increased from 11 to two to 13.
The Daemon threads increased from 8 to two and became 10.
VisualVM's thread label provides three views, which are displayed by default in the timeline, such as:
You can see two threads that are starting in our run Program: My-thread-1 and My-thread-2.
There are also two different views, the table view and the detail view, which look at the detailed view of each thread:
# # #转载注明出处: http://www.cnblogs.com/wade-xu/p/4369094.html
Another deadlock program, see if VISUALVM can analyze it.
PackageJVISUALVM; Public classDeadLock { Public Static voidMain (string[] args) {Resource R1=NewResource (); Resource R0=NewResource (); Thread myTh1=NewLockThread1 (R1, R0); Thread MyTh0=NewLockThread0 (R1, R0); Myth1.setname ("DeadLock-1"); Myth0.setname ("DeadLock-0"); Myth1.start (); Myth0.start (); }} classResource {Private inti; Public intGeti () {returni; } Public voidSetI (inti) { This, ib=i; } } classLockThread1extendsThread {PrivateResource R1, R2; PublicLockThread1 (Resource R1, Resource r2) { This. R1 =R1; This. r2 =R2; } @Override Public voidrun () {intj = 0; while(true) { synchronized(R1) {System.out.println ("The first thread got R1 ' s lock" +j); synchronized(R2) {System.out.println ("The first thread got R2 ' s lock" +j); }} J++; } } } classLockThread0extendsThread {PrivateResource R1, R2; PublicLockThread0 (Resource R1, Resource r2) { This. R1 =R1; This. r2 =R2; } @Override Public voidrun () {intj = 0; while(true) { synchronized(R2) {System.out.println ("The second thread got R2 ' s lock" +j); synchronized(R1) {System.out.println ("The second thread got R1 ' s lock" +j); }} J++; } } }
Open VISUALVM detected JVM process, we can see this tab is flashing, VISUALVM has detected my package under the deadlock class error
Switch to Thread tab and you can see the deadlock, Deadlock detected!
You can also click the thread dump thread dump, further analysis, here will not repeat, interested readers can experiment on their own.
Reference documents:
http://www.ibm.com/developerworks/cn/java/j-lo-visualvm/
Through the introduction of this article, I believe that the reader has a preliminary understanding of performance analysis, if you think the content of this article to your study is helpful, you can click on the lower right of the recommendation button, your encouragement is my creative power.
Reprint Annotated Source: http://www.cnblogs.com/wade-xu/p/4369094.html
Performance analysis Artifact VISUALVM