What is a permanent generation (PermGen) memory leak for Java

Source: Internet
Author: User
Tags stack trace apache tomcat

http://www.codelast.com/?p=7248

Reprint Please specify source: http://www.codelast.com/

This article is my translation of this article: What is a PermGen leak? For readability, I enclose the original text here, where translation is interspersed. In addition, in order to prevent the original link in the future after the expiration of the text in the picture can no longer see the problem, I will also save the original image of the site on the server, I do not know whether the original author is allowed to do so, but I translate this article only in the purpose of disseminating knowledge, the original author expressed deep gratitude:

What is A permgen LEAK?
What is a permanent generation (PermGen) memory leak for Java?

What follows was a practical introduction to a specific type of memory problems in Java applications. Namely–we would analyze the errors that cause the java.lang.OutOfMemoryError:PermGen spacesymptom in the stack Trace.
This article provides a practical introduction to a special memory problem with Java programs, that is, we will analyze the cause of the Java.lang.OutOfMemoryError:PermGen space error in the stack trace.

First of all we'll go through the core concepts required to understand the Subject–and explain what objects, classes, Classloaders and the JVM memory model is. If you is familiar with the basic concepts, you can jump directly to the next section where I'll describe II typical C ASEs for the error in question alongside with hints and suggestions for solving it.
First, let's take a look at the core concepts needed to understand the topic, and explain what objects (objects), classes (classes), Class loaders (Classloaders), and JVM memory models (JVM Memories model) are. If you are already familiar with these basic concepts, you can skip directly to the next section, where I discuss two typical reasons for generating the error, as well as tips and suggestions for resolving the problem.
Article Source: http://www.codelast.com/

Objects, Classes and Classloaders

Objects (Objects), classes (Classes), and Class loaders (classloaders)

Well, I won't start with the very basics. I guess if you had already found us, you should was familiar with the concept that everything in Java was an object. And that all Objects is specified by their Class. So every object have a reference to an instance of Java.lang.Class describing the structure of this object ' s Class .

But what actually happens under the hood, when do you create a new object in your code? For example if your write something truly complicated like

I won't start with the most basic concepts. I assume that you already know us, you should be familiar with it: in Java everything is an object, and all objects are specified by their classes (class). So each object has a reference to an instance of Java.lang.Class, which describes the structure of the object. But what happens when you create a new object in your code? For example, when you write the following code:

1 Person boss = newPerson();

The Java Virtual machine (JVM) needs to understand the structure of the object to create. To achieve this, the JVM looks for the class called person. And if the PersonClass is accessed for the first time during this particular execution ofLoadedBy the JVM, normally from the correspondingPerson.classFile. The process of seeking for thePerson.classFile on the drive, loading it into memory and parsing it's structure is calledclass Loading. Ensuring proper class loading process is the responsibility of aClassLoaderClassloaders is instances ofJava.lang.ClassLoaderClass and each and every class in a Java program have to be loaded by someClassLoader.As a result we now have the following relationships:
The Java Virtual machine (JVM) needs to understand the structure of the object to be created, for which the JVM looks for a class called person. Also, if the person class is first accessed during this run of the program, it must be loaded by the JVM (loaded), which is typically loaded from the corresponding Person.class file. The process of looking up a Person.class file from disk, loading it into memory, and parsing its structure is called Class loading (class loading). It is the responsibility of the class loader (ClassLoader) to ensure that the appropriate class is loaded. ClassLoader is an instance of the Java.lang.ClassLoader class, and every class in a Java program must be loaded by some classloader. Finally, we can get the following diagram:

Article Source: http://www.codelast.com/
As can see from the next diagram every ClassLoader holds references to all the classes it had loaded. For the purpose of our article these relationships is very interesting.
From the next picture you can see that each classloader holds a reference to all the classes it loads. Because of the main thrust of this article, these relationships are interesting.

Remember This image, we'll need it later.
Remember this picture, we'll use it later.
Article Source: http://www.codelast.com/

Permanent Generation

Permanent generation

Almost every JVM nowadays uses a separate region of memory, called the Permanent Generation (orPermGen for short) , to hold internal representations of Java classes. PermGen is also used to store more information–find out the details from this post if you were interested–but for our A Rticle It is safe to assume, the class definitions is being stored in PermGen. The default size of this region on my machines running Java 1.6 are not a very impressive 82MB.
Today, almost all JVMs use a separate memory region called the permanent generation (Permanent Generation, or abbreviated as PermGen) to preserve the intrinsic characterization of the Java class. PermGen is also used to save more information-you can look at this article if you are interested-but for this article, we can assume that PermGen only saves the definition of the class. For my machine running Java 1.6, the default size of this memory area is 82MB, a very common value.


As I has explained in one of my earlier posts, a memory Leak in Java was a situation where some objects are N O longer used by a application, but the  garbage Collector  fails to recognize them as unused. This leads to the , outofmemoryerror  if Those unused objects contribute to the heap USA GE significantly enough that's next memory allocation request by the application cannot is fulfilled.
As I explained in a previous article, the memory leak in Java means that some objects are no longer used by the application, and the garbage collector (garbage Collector) does not recognize them as "unused". If the unused object takes up heap space large enough to make the application unable to meet the next memory allocation requirement, it can cause outofmemoryerror errors.

The root cause of Java.lang.OutOfMemoryError:PermGen space is exactly the same:the JVM needs to load the Defini tion of a new class but there was not enough space in PermGen to does It–there are already too many classes stored there. A possible reason for this could is your application or server using too many classes for the current size of PermGen not To is able to accommodate them. Another commone reason could be a memory leak.
The root cause of the Java.lang.OutOfMemoryError:PermGen space error is exactly the same: the JVM needs to load a new class definition, and the Permanent generation (PermGen) is out of space-there are too many classes stored there. One possible reason is that your application or server is using too many classes, and the current permanent generation (PermGen) size does not meet the requirements. Another reason may be a memory leak.
Article Source: http://www.codelast.com/

Permanent Generation Leak

Permanent generation (memory) leaks

But still, what on Earth it's possible to leak something in PermGen? It holds definitions of Java classes and they cannot become unused, can they? Actually, they can. In case of a Java Web application deployed to an application server all those classes in your Ear/war become worthless W Hen the application is undeployed. The JVM continues to run as the application server was still alive, but a whole bunch of class definitions was not in use a Nymore. And they should is removed from PermGen. If not, we'll have a memory leak in the PermGen area.
However, is there any possibility of a memory leak in the permanent generation (PermGen)? It preserves the Java class definitions, and these class definitions do not become "useless", do they? In fact, they can become "useless". For a Java Web program deployed to an application server, all the classes in your Ear/war package will become useless when the application is unloaded. As long as the application server is alive, the JVM will continue to run, but a whole bunch of class definitions will no longer be used and should be removed from the permanent generation (PermGen). If we do not remove it, we will have a memory leak in the permanent generation (PermGen) area.

As a nice sample on the reasons–the Tomcat developers has set up a Wiki page describing different leaks found and fixed In the Apache Tomcat versions 6.0.24 and above.
Here's a good example of why a memory leak is being described.--tomcat's developers wrote a wiki page describing the different causes of memory leaks found and repaired in Apache Tomcat 6.0.24 and later.
Article Source: http://www.codelast.com/

Leaking Threads

Thread memory leaks

One possible scenario for a classloader leak is through long running threads. This happens when your application Or–as often is the case in my Experience–a 3rd party library used by your Applicat Ion, starts some long running thread. An example of the could be a timer thread whose job was to execute some code periodically.
One possible scenario for the class loader (ClassLoader) leak is through the running thread (and memory leaks). When your program, or your program uses a third-party library (which I often encounter), turns on some long-running threads. An example: a timer (timer) thread that is used to periodically execute code.

If the intended lifespan of this thread was not fixed, we were heading directly into a trouble. When any part of your application ever starts a thread, you must make sure it's not going to outlive the application . In typical cases the developer either are not aware of this responsibility or simply forgets to write the clean-up code.
If we don't address the expected life cycle of the thread, we'll have a direct problem. When you start a thread in any part of your program, make sure it doesn't live longer than the program. In a typical situation, the developer either doesn't know that he or she has a responsibility to deal with the problem, or forgets to write the clean-up (clean-up) code.

Otherwise, if some thread continues to run after the application is undeployed, it'll, usually, hold a reference to a CL Assloader of the Web application It is started by, called context ClassLoader. Which in turn means, all classes of the undeployed application continue to being held in memory. Remedy? If It is your application this starts new threads, you should shut them down during undeployment using a servlet context L Istener. If It is a 3rd party library, you should search for its own specific shutdown hook. Or file a bug report if there is none.
Otherwise, if the application is unloaded and the thread continues to run, it will typically maintain a classloader reference to the Web application, which is what we call the context ClassLoader. This means that all uninstalled applications are still in memory. How to solve? If your program opens new threads, you should close them when uninstalling, which can be done by using a servlet context listener. If it is a new thread opened by a third-party library, you should search for its thread-off interface, and if not, escalate a bug.
Article Source: http://www.codelast.com/

Leaking Drivers

Drive memory leaks

Another typical case of a leak can is caused by database drivers. We have encountered the leak In our own demo application that we ship with PLUMBR. It's a slightly modified Pet Clinic application shipped along with Spring MVC. Let us highlight some things it happen when this application was being deployed to the server. The
Another typical memory leak is caused by a database driver. We encountered this memory leak in the demo program that we released with PLUMBR. It is a pet clinic program that was released with Sprint MVC and has a slightly modified code. Let's take a look at what happens when this application is deployed to the server:

    • The server creates a new instance of Java.lang.Classloader and starts to load the application ' s classes using it.
    • The server creates a new instance of Java.lang.Classloader and uses it to load the program's class.
    • Since the petclinic uses a HSQL database, it loads the corresponding JDBC driver,org.hsqldb.jdbcDriver
    • Because Petclinic uses the Hsql database, it loads the corresponding JDBC driver, which is the Org.hsqldb.jdbcDriver
    • This class, being a good-mannered JDBC driver, registers itself with Java.sql.DriverManager during initialization , as required per JDBC specification. This registration includes storing inside a static field of DriverManager a reference to an instance of Org.hsqldb.jdb Cdriver.
    • This JDBC driver class will register it in Java.sql.DriverManager at initialization time (as required by the JDBC specification). This registration process includes a reference to an instance of storage Org.hsqldb.jdbcDriver to a static domain in DriverManager

Now, when the application was undeployed from the application server, theJava.sql.DriverManagerWould still hold this reference, as there is no code in the HSQLDB library and the Spring framework nor in the Applicati On to remove that! As was explained above, aJdbcdriverObject still holds a reference to anOrg.hsqldb.jdbcDriverclass, which in turn holds a reference to the instance ofJava.lang.ClassloaderUsed to load the application. This classloader now still reference all the classes of the application. In case of our particular demo application, during application startup almost, classes is loaded, occupying roughly 1 0MB in PermGen. Which means that it takes on 5-10 redeploys to fill the PermGen with default size to reach theJava.lang.OutOfMemoryError:PermGen SpaceCrash.
Now, when uninstalling an application from the server, Java.sql.DriverManager still holds that reference, no code can remove it in the Hsqldb library, or in the Spring framework! As explained above, a Jdbcdriver object will hold a reference to the Org.hsqldb.jdbcDriver class, holding a reference to an instance of the Java.lang.Classloader used to load the application. This classloader still references all classes of the application. In our special demo application, when the program starts, it needs to load nearly 2000 classes, occupying approximately 10MB of permanent generation (PermGen) memory. This means that the 5~10 will need to be redeployed before the default size of the permanent generation (PermGen) is filled, and then the Java.lang.OutOfMemoryError:PermGen space error is triggered and crashes.

How do I fix that? One possibility is to write a servlet context listener, which de-registers the HSQLDB driver from DriverManager D uring application shutdown. This is pretty straightforward. But remember–you'll has to write the corresponding code in every application using the driver.
How do I resolve this issue? One possible way is to write a servlet content listener, which is used to reverse-register HSQLDB drivers from DriverManager when the application is closed. This approach is straightforward, but keep in mind-you need to write this in every application that uses that driver.

Download our latest version of PLUMBR with our demos application and play with it to find out how the leak occurs, how Plum BR finds it and how do we explain the cause.
Download our latest version of the PLUMBR and demo app to see how the memory leak happened, how plumbr found it, and how we explained its cause.
Article Source: http://www.codelast.com/

Conclusion

Conclusion

There is many reasons why your application might encounter a  java.lang.outofmemoryerror:permgen space . The root cause for the majority of them are some reference to an object or a class loaded by the application ' s class Loade R that have died after. Or a direct link to the class loader itself. The actions for remedy is quite similar for most of these causes in need to take. Firstly, find out where the reference is being held. Secondly, add a shutdown hook to your Web application to remove the reference during application ' s undeployment. You can do this by either using a servlet context listener or by using the API provided by your 3rd party library.
There are many reasons why your application encounters java.lang.OutOfMemoryError:PermGen space errors, most of which are due to the fact that the reference to the class loader loaded by the object or program class is useless. The remedy you need to take on such a problem is very similar, that is, first, find out where the reference is held; Next, add a closed hook to your Web application, or remove the reference after the application unloads. You can do this either through the servlet context listener or through the API provided by the third-party library.

Finding those leaking references have never been easy. We ourselves has spent countless hours trying to trace off why some applications require 20MB of PermGen on each Redeplo Y. But as of version 1.1, PLUMBR would show you the cause of the leak and give you a hint on how to fix it. If you want-to-try it out, register and download the tool. If you are running a older version of PLUMBR, we strongly recommend downloading an upgrade.
Finding a reference to a memory leak is never an easy thing to do. For example, for our own part, we have spent countless hours tracking why some programs require 20MB of permanent generation (PermGen) memory for each deployment. However, PLUMBR version 1.1 can tell you the cause of the memory leak and give you a fix hint. If you want to try it, sign up to download it. If you are still using the old version of PLUMBR, we strongly recommend that you upgrade to the new version.

What is a permanent generation (PermGen) memory leak for Java

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.