Performance analysis Tools-Eclipse Memory Analyzer tool (MAT) (iii) "Turn"

Source: Internet
Author: User
Tags modifiers uppercase letter

Perm Gen


As we know in 2 articles, Perm Gen is a heterogeneous store of class and method data (related to class loader) and interned strings (string dwell). There is not too much Perm gen information in the heap dump. So let's use that little bit of information to solve the problem.

Look at the code below and use interned strings to burst the perm Gen.

/**
* Oompermtest Class
* @author Rosen Jiang
*/
Package org.rosenjiang.test;

public class Oompermtest {
public static void Main (string[] args) {
Oom ();
}

private static void Oom () {
object[] array = new object[10000000];
for (int i=0; i<10000000; i++) {
String d = string.valueof (i). Intern ();
Array[i]=d;
}
}
}


The console prints the following information and then imports the Java_pid1824.hprof file into the mat. In fact, in mat, the situation should be similar to "Outofmemoryerror:java heap space" (using an array), because heap dump does not contain any information about interned strings. It is important to emphasize here that you should pay more attention when using the Intern () method.

Java.lang.OutOfMemoryError:PermGen Space
Dumping Heap to Java_pid1824.hprof
Heap dump file created [121273334 bytes in 2.845 secs ]
Exception in thread "main" Java.lang.OutOfMemoryError:PermGen space



Is thinking about how to put the class loader burst to waste some thoughts. After trying, it is found that using ASM to dynamically generate classes can achieve the goal. The main role of ASM (http://asm.objectweb.org) is to process the compiled class (compiled Class), to build, transform, parse (one of the functions is to implement dynamic proxy) of the compiled class, and it runs fast and small enough, and the document is comprehensive. It's a must-haves at home. ASM provides the core API and the tree API, which is an event-based approach, which is object-based, similar to XML sax, Dom parsing, but there is a loss of performance using the tree API. Since ASM is used below, it has to be wordy about the structure of the compiled class, including:
1, modifiers (such as public, private), class name, parent class name, interface, and Annotation section.
2, class member variable declaration, including the modifier, name, type, and annotation of each member.
3, methods and constructor descriptions, including modifiers, names, return and incoming parameter types, and annotation. Of course, they also include the specific Java bytecode for these methods or constructors.
4. Chang (constant pool), constant pool is an array of numbers, strings, and type constants that appear in a class.



The source difference between the compiled class and the original class is that the compiled class contains only the class itself, and the inner class does not appear in the compiled class, but instead generates another compiled class file, and second, there is no comment in the compiled class; third, the compiled class has no package and import parts.
And here we have to talk. The description of the compiled class to the Java type, represented by a single uppercase letter for the original type, Z for Boolean, C for Char, b for Byte, s for short, I for int, F for float, j for long, and D for double While the description of the class type is represented by the internal name (internal name) plus the prefix L and the following semicolon, the so-called internal name is a notation with an all-inclusive path, such as a String whose internal name is java/lang/string, and for the array type, Use the square brackets to describe the way the data element type is used. Finally, the description of the method, expressed in parentheses, if the return is void with V, the specific reference.



The following code uses the ASM core API, noting that interface Classvisitor is the core, and Fieldvisitor, Methodvisitor are secondary interfaces. Classvisitor should be called in such a way: visit Visitsource? Visitouterclass? (visitannotation | visitattribute) * (Visitinnerclass | visitfield | visitmethod) * visitend. That is to say, the visit method must call first, then call the Visitsource at most once, then call the Visitouterclass method at most once, then call the Visitannotation and Visitattribute methods more than once. Finally, the Visitinnerclass, Visitfield, and Visitmethod methods are called multiple times. Call the Visitend method as the end after the call is finished.

Note that the Classwriter class, which implements the Classvisitor interface, can construct the compiled class directly into a binary form by Tobytearray method. Because we want to dynamically generate subclasses, we are only interested in classwriter. The first is the abstract class prototype:

/**
* @author Rosen Jiang
* Myabsclass Class
*/
Package org.rosenjiang.test;

Public abstract class Myabsclass {
int less =-1;
int EQUAL = 0;
int GREATER = 1;
abstract int Absto (Object o);
}


Next is the custom class loader, really cannot, ClassLoader's DefineClass method All is protected, wants to load the byte array form (because Tobytearray) the class only then inherits oneself to implement again.

/**
* @author Rosen Jiang
* Myclassloader Class
*/
Package org.rosenjiang.test;

public class Myclassloader extends ClassLoader {
Public Class defineclass (String name, byte[] b) {
Return DefineClass (name, b, 0, b.length);
}
}


Finally, the test class.

/**
* @author Rosen Jiang
* Oompermtest Class
*/
Package org.rosenjiang.test;

Import java.util.ArrayList;
Import java.util.List;
Import Org.objectweb.asm.ClassWriter;
Import Org.objectweb.asm.Opcodes;

public class Oompermtest {
public static void Main (string[] args) {
Oompermtest o = new Oompermtest ();
O.oom ();
}

private void Oom () {
try {
Classwriter cw = new Classwriter (0);
Cw.visit (opcodes.v1_5, Opcodes.acc_public + opcodes.acc_abstract,
"Org/rosenjiang/test/myabsclass", NULL, "Java/lang/object",
New string[] {});
Cw.visitfield (opcodes.acc_public + opcodes.acc_final + opcodes.acc_static, "less", "I",
NULL, New Integer ( -1)). Visitend ();
Cw.visitfield (opcodes.acc_public + opcodes.acc_final + opcodes.acc_static, "EQUAL", "I",
NULL, new Integer (0)). Visitend ();
Cw.visitfield (opcodes.acc_public + opcodes.acc_final + opcodes.acc_static, "GREATER", "I",
NULL, new Integer (1)). Visitend ();
Cw.visitmethod (Opcodes.acc_public + opcodes.acc_abstract, "Absto",
"(Ljava/lang/object;) I", NULL, NULL). Visitend ();
Cw.visitend ();
Byte[] B = Cw.tobytearray ();

list<classloader> classloaders = new arraylist<classloader> ();
while (true) {
Myclassloader ClassLoader = new Myclassloader ();
Classloader.defineclass ("Org.rosenjiang.test.MyAbsClass", b);
Classloaders.add (ClassLoader);
}
} catch (Exception e) {
E.printstacktrace ();
}
}
}


In a moment, the console gave an error.

Java.lang.OutOfMemoryError:PermGen Space
Dumping Heap to Java_pid3023.hprof
Heap dump file created [92593641 bytes in 2.405 secs ]
Exception in thread "main" Java.lang.OutOfMemoryError:PermGen space


Opens the Java_pid3023.hprof file, taking a look at the classes:88.1k and class loader:87.7k sections, from which you can see that class Loader loads a large number of classes.



For further analysis, select the Java basics--class Loader Explorer feature by clicking the button in the Red box coil. Open to see the interface shown, the first column is the class loader name, the second column is the number of class loader defined classes (defined classes), here to say the defined classes and loaded classes (loaded classes), when the need to load the class , the corresponding class loader will first delegate the request to the parent class loader, and only if the parent class loader fails to load, that class loader will define and load the class itself, which is the Java own "parent delegate load Chain" structure The third column is the number of instances of classes loaded by class loader.



Here in class Loader Explorer, you can see if class Loader has loaded too many classes. In addition, there are duplicate classes functions, but also to assist in the analysis of repeated loading of the class, here is no longer, it is certain that Myabsclass was repeatedly loaded n times.

Last

In fact, the mat tool is very powerful, the above-mentioned example code does not use the other MAT analysis function, so it is no longer described. In fact, for Oom not only I enumerated two kinds of overflow errors, there are a number of other errors, but I want to say, for Perm Gen, if it is really not the problem, it is recommended to use the JVM's-verbose parameter, which will print out the log in the background, can be used to see which class Loader What class was loaded, for example: "[Loaded Org.rosenjiang.test.MyAbsClass from Org.rosenjiang.test.MyClassLoader]".
The full text is complete.


references

Memoryanalyzer Blog
Java class loader architecture
ClassLoader

Performance analysis Tools-Eclipse Memory Analyzer tool (MAT) (iii) "Turn"

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.