Class loader - the memory leak problem of a

分类:Java 2010-07-29 来源 人气:291

About websphere console to restart the application, rather than restart the websphere, this time a static class can not be recovered, resulting in some classes can not be destroyed, occupied by the memory, but this memory can not be reused, can be said that the memory leak. Static class can not be destroyed, then the static class reference to an object can not be destroyed, so some bean not be normal recovery, in fact, occupied by the memory of these small objects are very few, most notably in reference to these classes do not destroy the cache, the cache the bulk of memory is occupied. If the system used a couple of days, and then someone in the console will restart the application, then the cache will not be destroyed, according to a waste into a lot of memory, so now we analyze the dump file, half of the memory cache is not destroyed by these non- occupied with the cache. In fact, BSP has a HttpServletContextListener, the listener be able to empty the cache when the application closed, but you can see from the dump file, this listener may not have time to call in the application closed.

Support for static class objects destroyed some issues need to study and solve Websphere this bug.


Therefore, we believe that the Bug is caused WAS: application to re-start the process of making some kind of Class MetatData describes itself can not be released from memory, while the tobacco system in LouShang some type of system for a large class of class Class static variables defined and static variables in these classes store a large number of objects. Over time, several times to restart the application to large amount of memory being used, leading to memory leaks.

Java static class for supplementary explanation: usually not allowed to declare a general class of static, only one internal class can. In an internal class provides static methods if you want to visit the premise, we will put this internal class is set to a static class. Then do not need an external instance of class and inner classes, but can directly call within the static method. Sample as follows:

view plain print?

  1. package com.test;
  2. public class StaticCls (
  3. public static void main (String [] args) (
  4. OuterCls.InnerCls.test ();
  5. )
  6. )
  7. class OuterCls (
  8. public static class InnerCls (
  9. public static void test () (
  10. System.out.println ("InnerCls");
  11. )
  12. )
  13. )

I believe in LouShang tobacco system application scenarios of this static class is rare, so the above-mentioned static class is not quite accurate, and should be corrected as follows: class static variables.

While the "static class" to "class static variable", but the above-mentioned Class MetatData class itself can not be described to be released from memory problems do exist. In the week of constant total December 14 issue of e-mail asking HeapAnalyzer have a very intuitive picture can explain the problem, the analysis of the actual production environment HeapDump document icons as follows:

Class loader - the memory leak problem of a

One class org / loushang / bsp / organization / domain / support / Stru describes the properties of this class Stru itself:

a) One Size (304) is to describe its size class Stru

b) which No.Child (43) describes Stru class and methods for all variables used in reference to the class to the number of

c) which TotalSize (348,544,600) describes this Stru all references to the class and methods used to the size of the classes and methods + all references to the instance of the class used to the size of an object, all values larger. But only by the figure above listed TotalSize (348,544,600) does not directly state that causes abnormal memory usage from Stru

In a week of constant total e-mail reply, I said: "In the figure, there are two different addresses, different size class org / loushang / bsp / organization / domain / support / Stru it is some weird. General (in the normal class loader to run the course) will only exist in memory in the current class description of a Class. "

At that time I just feel more strange: Why are there two in memory of the Class Stru class description? But did not pay sufficient attention: that it is a serious problem.

Constant in subsequent weeks, the overall message that:

"We are the technical staff by testing, found two class problem yes a Websphere the bug, restart ear after the application of static variables and object references will not be released. Mei Yi Ci reboot one more class on the line."

Guards then the total message on December 19 that the message here:

"By restarting the console does not release the static variable. Was the intention to do so, or whether this conclusion is incorrect?"

Thus, the formation of a proposition:

In the WAS server, if the restart J2EE application (not restart the WAS server), certain types of classes can not be recovered from memory. Restart application may result in multiple memory leak?

This is not WAS a Bug?

Question: Application restart, resulting in memory leak?

To address this question, we can turn to Google to get some clues, we can search key words: OutOfMemoryError redeploy, restart the application to obtain information on a wealth of information leading to memory leaks.

We have a few more classics to share with you:

1, the repeated deployment of JBOSS start the application server will result in OutOfMemory
Description: OutOfMemory error when repetatively deploying and undeploying with 10 minute interval
Remains unresolved

2, why repeat the deployment of applications will continue to lead to increased use of Tomcat memory?
Description: Why does the memory usage increase when I redeploy a web application?
Remains unresolved

3, SUN JDK + Tomcat 5.5.20 to run the service when a problem, restart the application, the server will hang after a few days and report to java.lang.OutOfMemoryError: PermGen space exception.
Description: The inference may be caused due SUN JDK's BUG is loaded into the SUN JVM Perm region Class can not be recycled lead to memory leaks, recommend using IBM JDK or BEA JRokit virtual machine to solve the problem. (My comment: Actually, not a JVM BUG result)

4, that is the Spring leading to OutOfMemory, start the great debate

5, some considered to be caused by SUN JDK Bug
Description: In 2003, when there is a bug report to the sun, but until now, this bug has not close! This bug was added in the sentence reviews: "A bug this critical is open since 2003? Absolutely shameful." Do you think that SUN BUG indeed some of this disgrace, in fact, do not think this is a JVM SUN BUG itself caused, must be applied BUG itself caused.

Really different opinions, there is no exact answer.

But we can be more common this problem, look not because of WAS application server, JDK / JRE, Tomcat, Spring, Hibernate and other middleware Bug caused the following to describe what we would guess:

1, for the Class of the MetaData class description is in the SUN JDK in memory PermGen space dedicated to storage (PermGen space full name is the Permanent Generation space, is the permanent preservation areas of memory, this memory is stored mainly by JVM Class and Meta information, Class Loader time being will be put PermGen space, it and store class instance (Instance) of the Heap regional differences), but the default PermGen space is relatively small for the 4M. So once the application to restart and there is duplication of the same Class loading conditions, can easily lead to PermGen overflow, which directly led to "java.lang.OutOfMemoryError: PermGen space" appear.
For using IBM JDK or BEA JRokit JVM seems to solve the problem, in fact, does not fundamentally resolve the Class class to repeat loading problem. Only in the IBM JDK or BEA JRokit JVM contains no specific PermGen space to store Class class description, but sharing space with the JVM Heap, so repeat the loaded Class does not immediately lead to memory overflow. But the cumulative, the problem will still be apparent, as the general issue of Tobacco.

2, why the same question in different J2EE platforms, different J2EE framework, have also experienced different JDK? Does not seem to result from these middleware Bug, Are these different vendors, developers of the code there is the same Bug?

Really speak louder than words, we use the facts speak for it: we try to develop some scenarios to reproduce the problem.

Reproduce the problem

How to restart the application to judge the Class class to repeat after loading problems?

Class is repeated for the loading of the problem, all the JVM Profiling the market can not be effective diagnostic tools to track and debug. The only possible way: that is a problem using the IBM JVM running the application, through the JVM interface or Unix environment, kill -3 <Java_PID> way to generate the current JVM HeapDump JVM file, thus we can use the IBM HeapAnalyzer tools to analyze whether there is duplication of Class class loading problem.

To simplify the process generate Java HeapDump, we specifically developed for JSP pages generated HeapDump documents to facilitate our Windows platform testing and validation.
Class loader - the memory leak problem of a


view plain print?

  1. <! DOCTYPE HTML PUBLIC "- / / W3C / / DTD HTML 4.01 Transitional / / EN" "">
  2. <% @ Page language = "java" contentType = "text / html; charset = GB18030" pageEncoding = "GB18030"%>
  3. <Html> <head>
  4. <Title> dump </ title>
  5. <Meta http-equiv = "Content-Type" content = "text / html; charset = GB18030"> </ head>
  6. <Body>
  7. <H2> generate HeapDump and JavaCore </ h2>
  8. <% String heapdumpCmd = request. GetParameter ("heapdump");
  9. if (heapdumpCmd! = null) ();
  10. String javacoreCmd = request. GetParameter ("javacore");
  11. if (javacoreCmd! = null) ();
  12. String gcCmd = request. GetParameter ("gc");
  13. if (gcCmd! = null) System.gc ();%>
  14. <Form action = "dump.jsp">
  15. <Input type = "submit" name = "gc" value = "GarbageCollection">
  16. <Input type = "submit" name = "heapdump" value = "CreateHeapDump">
  17. <Input type = "submit" name = "javacore" value = "CreateJavaCore"> </ form>
  18. </ Body>
  19. </ Html>

Attempt to repeat the preparation of sample reproducibility Class loading problem

Development Center under the wave and the wave of the tobacco research center in the feedback has been considered a static variable used as class leading Class can not be released to appear Class repeated loading problem. To this end we simulate the following code:

view plain print?

  1. public class ClassLoadBugServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet (
  2. private static byte [] testByteArray = new byte [2024000];
  3. public ClassLoadBugServlet () (super ();)
  4. protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException (
  5. perform (request, response);
  6. )
  7. protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException (
  8. perform (request, response);
  9. )
  10. private void perform (HttpServletRequest request, HttpServletResponse response) throws IOException (
  11. StaticClass sc = new StaticClass ();
  12. response.getOutputStream (). print (sc.test ());
  13. System.out.println (sc.test ());
  14. )
  15. )

view plain print?

  1. public class StaticClass (
  2. private static byte [] testByteArray = new byte [2024000];
  3. public String test () (return "Test Class Loader";)
  4. )

Use the above code, we deployed to the WAS for the corresponding test, repeat run, restart the application dozens of times, using the above dump.jsp produce what we need JVM HeapDump, and then use the IBM HeapAnalyzer analyzed, and no we mention above to the Class repeat loading problem.

Experiment is a win.

Class loading problem can be reproduced repeat

Wave of software based wave of tobacco and LouShang v3 v3 core of the system in the Spring Framework platform, and there are pages in the Internet web site reflect the existence of Class Spring platform repeated loading problem t = 21383 & highlight = cglib + cache & page = 4

To this end we transform the above sample to use Spring Framework to load StaticClass, to further verify the existence of Class repeated loading problem.

view plain print?

  1. public class ClassLoaderTestServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet (
  2. public ClassLoaderTestServlet () (super ();)
  3. protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
  4. (Perform (request, response);)
  5. protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
  6. (Perform (request, response);)
  7. private void perform (HttpServletRequest request, HttpServletResponse response) throws IOException (
  8. StaticClass sc = (StaticClass) getClassPathApplicationContext (). GetBean ("staticClass");
  9. response.getOutputStream (). print (sc.test ());
  10. System.out.println (sc.test ());
  11. )
  12. private ApplicationContext getWebApplicationContext ()
  13. (WebApplicationContext wac = null;
  14. wac = (WebApplicationContext) getServletContext (). getAttribute (WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
  15. return wac;
  16. )
  17. private ApplicationContext getClassPathApplicationContext ()
  18. (ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext ("spring / serviceContext.xml");
  19. return context;
  20. )
  21. )

spring / serviceContext.xml

view plain print?

  1. <? Xml version = "1.0" encoding = "GBK"?>
  2. <Beans xmlns = ""
  3. xmlns: xsi = ""
  4. xmlns: aop = ""
  5. xsi: schemaLocation = "
  6. "
  7. default-autowire = "byName" default-lazy-init = "true">
  8. <Bean id = "staticClass" class = "com.test.StaticClass" />
  9. </ Beans>

The same way we use the above code, deploy to WAS for the corresponding test, repeat run, restart the application dozens of times, using the above dump.jsp produce what we need JVM HeapDump, and then use the IBM HeapAnalyzer analysis, culminating in our Repeat the above-mentioned Class loading problem.

Is Spring the Bug class has led to repeated load Class? Unthinkable?

In order to locate there in the Spring Class of repeated loading, we need to elaborate on the JVM memory garbage collection, and load the basic principles of class Class.

JVM GC overview of garbage collection

JVM GC Java Virtual Machine that is the JVM garbage collection mechanism for the release of those objects are no longer using the memory. JVM Java language does not require a GC, GC did not provide for how they work. However, the JVM have used GC, and most use a similar algorithm GC memory management and implementation of collection operations.

The purpose is to clear the garbage collection of objects no longer in use, and now most of the JVM traverse through the use of object references the way (to determine whether the object referenced by activities) to determine whether the collection of the (garbage) objects. Traverse object references starting from the root thread object, along the entire object graph on each object reference links, can be reached recursively determine the (reachable) objects. If an object can not reach the root of the thread object reference, will be collected as garbage.

Class class loading mechanism of these

Such as the IBM WAS J2EE application server to allow the preparation of a number of J2EE application EAR / WAR deployment to the same J2EE application server. If one changes one J2EE application, and we long for this EAR / WAR to be updated, re-deployment, start the EAR / WAR application, does not need to re-start the deployment where the application server, which does not affect the deployment of the same application server other applications running.

The realization of this function is mainly due to WAS and other J2EE server, for different application EAR / WAR ClassLoader provides a different class loader, the ClassLoader used to load their own Class class, Guer different EAR / WAR application between will not affect each other. ClassLoader itself is simply a standard Java Class (provided by the J2EE container), but its special in just for the load in / WEB-INF/classes or JAR file in the Class class. Under normal circumstances, when you stop the application, this application's ClassLoader EAR J2EE application server will be discarded as waste, Guer all this EAR ClassLoader class loader that loaded the class will be discarded as garbage, finally recovered for JVM GC.

The J2EE application server in all there different levels of ClassLoader, is our WAS application server as an example (please refer to the other server ClassLoader " Tomcat and Websphere class loading mechanism "):

Websphere class loading mechanism

Java application running, in the Class of implementation and be visit, it must pass class loader loads to be effective, JVM class loader is part of the code which is responsible for the virtual Machine JVM to locate and load all Java classes and local lib library. Class loader effects of different configurations to the application deployment to application server run-time behavior. JVM and WebSphere Application Server provides a variety of different class loader configuration, forming a hierarchical structure with parent-child relationship.

WebSphere class loader in the hierarchy icon

Class loader - the memory leak problem of a

As shown above, WebSphere in the class loader to be organized into a top-down hierarchy, the top is the system environment JVM, the lowest level is a specific application, parent-child relationship between the upper and lower layers.

a) JVM Class loader: at the top of the hierarchy, it is the class loader hierarchy of the root, so it has no parent class loader. This class is responsible for load JVM class loader, JVM extension classes, and defined in the classpath environment variable on all the Java classes.

b) WebSphere Extensions Class loader: WebSphere Extension class loader, which loads the WebSphere some of the runtime class, the resource adapter classes and so on.

c) WebSphere lib / app Class loader: WebSphere server class loader, which loads the WebSphere installation directory under $ (WAS_HOME) / lib / app path class. Version in WAS v4, WAS use this path is shared between all applications jar package. Starting from the WAS v5, shared library function provides a better way, therefore, the class loader for a number of existing systems compatible.

d) WebSphere "server" Class loader: WebSphere Application Server class loader. It is defined in the server is shared between all applications of classes. WAS v5 in with the concept of shared libraries, you can define multiple application servers for the shared library associated with the class loader, they define the order in accordance with the formation of parent-child relationship.

e) Application Module Class Loader: application class loader, in the last layer of the hierarchy, is used to load J2EE applications. According to the application's class loading strategy of different Web modules can also define your own class loader.

On the WebSphere class loader hierarchy, for the following description may be more helpful to find and understand the class loading process:

a) Each class loader is responsible for the definition of the class in its own path to find and load classes.

b) a child class loader can delegate to its parent class loader to find and load the class, a class loading request from the child class loader will be sent to the parent class loader, but never from the parent sent to the child class loader class loader.

c) Once a class is successfully loaded, JVM will cache the class until the end of its life cycle, and it and the corresponding class loader associated with, which means that different class loader (or the lower grade level between) can be loaded with the same name of the class.

d) If a loaded class depends on one or several classes, these being dependent on the class must exist in this type of class loader search path, or the parent class loader search path.

If a class loader and all of its parent class loader can not find the class, the system will throw ClassNotFoundExecption NoClassDefFoundError exception or error.

JVM GC garbage collection and the ClassLoader class loader the delicate relationship between

If your application exists in the following similar code:

view plain print?

  1. private void x1 () (
  2. for (;;) (
  3. List c = new ArrayList ();
  4. )
  5. )

This code will run repeatedly to apply new ArrayList object memory space, but this code does not cause memory leaks OutOfMemory phenomenon. Because of the continuing application of a new ArrayList object will be immediately discarded as garbage object eventually recovered in the JVM GC process, and release the memory space occupied by the Heap, so we can continue to apply to the new object the required memory space.

Now we Servlet, for example, demonstrated under normal operating conditions the following code in memory usage

view plain print?

  1. public class Servlet1 extends HttpServlet (
  2. private static final String STATICNAME = "Simple";
  3. protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException (
  4. )
  5. )

When this Serlvet1 class is loaded into memory at run time, the following objects and classes Class object will exist in memory, interconnected relationships are shown below (the core of several classes and objects):

Class loader - the memory leak problem of a

The yellow box is identified by the application ClassLoader class loader (AppClassLoader) load of classes and the corresponding object class instance, the other to the green box are identified. One Graphic (simplified) of the J2EE container object Container reference point to the end J2EE applications to create the application class loader AppClassLoader object, at the same time reference also points to the application class loader created Serlvet1 loaded AppClassLoader instance object. When the external HTTP requests to this Servlet1, the container will call Servlet1 Container object instance doGet () method to provide services.

A few of them should draw attention to:

a) which are Class Servlet1 STATICNAME class all its own, not part of Servlet1 class instance object.

b) an instance of an object which contains the reference point Servlet1 Servlet1.class class itself.

c) Each Class class contains a reference point to load the Class class class loader AppClassLoader object.

d) At the same time each class loader object contains a reference point AppClassLoader classes loaded by Class

Icon from the above, we can clear that, if other than AppClassLoader class loader loaded the object refers to any object loaded by the AppClassLoader, then loaded by the AppClassLoader any Class (including AppClassLoader itself) will not be garbage collection. This conclusion is very important, which receive the above we describe the phenomenon of memory leaks Class fundamental reasons, followed by we will explain this phenomenon is Ruhe was triggered.

Under normal circumstances, if the application is deployed above unloaded or stopped, then the Container object to be associated with the application of any of classes and objects (such as Servlet1 instance of an object, AppClassLoader class loader instance) Disconnect the reference correlation, so these and stopped all application-related classes and class instances will be discarded as waste and JVM for recovery of memory.

Class loader - the memory leak problem of a

As shown above, Servlet1 application-related classes, objects, class loader objects, etc. All and all the root thread object has no association, which will eventually be JVM for garbage collection.

We now come to demonstrate a sample of non-normal circumstances, it is this "abnormal" result in the application of all the Class class can not be destroyed from memory the correct. Here we introduced the original sample Servlet1 a special Class class and its instances: Level, rewrite the sample code as follows:

view plain print?

  1. package com.test;
  2. import *;
  3. import java.util.logging .*;
  4. import javax.servlet .*;
  5. import javax.servlet.http .*;
  6. public class LeakServlet extends HttpServlet (
  7. private static final String STATICNAME = "This leaks!";
  8. private static final Level CUSTOMLEVEL = new Level ("test", 550) (); / / anon class!
  9. protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException (
  10. Logger.getLogger ("test"). Log (CUSTOMLEVEL, "doGet called");
  11. )
  12. )

Note that an anonymous type which CUSTOMLEVEL is an instance of an object class, the class constructor for Level property protected, can not be directly constructed, we must create a new class of new Level ("test", 550) (), to form LeakServlet of built-in class, the final compilation will generate LeakServlet $ 1.class

When this LeakServlet.class class is loaded into memory at run time, the following objects and classes Class object will exist in memory, each icon associated with the following (the core of several classes and objects):

Class loader - the memory leak problem of a

This icon appears in the unexpected sight of you: System Level class instance using a class static variable ArrayList to hold all created instances of all types of Level of objects, we can JDK Level class source code to verify:

view plain print?

  1. public class Level implements (
  2. private static java.util.ArrayList known = new java.util.ArrayList ();
  3. ... ...
  4. protected Level (String name, int value) (
  5. this (name, value, null);
  6. )
  7. protected Level (String name, int value, String resourceBundleName) (
  8. if (name == null) (
  9. throw new NullPointerException ();
  10. )
  11. this. name = name;
  12. this. value = value;
  13. this. resourceBundleName = resourceBundleName;
  14. synchronized (Level. class) (known.add (this);)
  15. )
  16. ... ...
  17. )

When the application is unloaded or stopped, then the JVM GC can do those things?

Class loader - the memory leak problem of a

Serious has happened, in all classes and instances of objects in the instance of the object is only LeakServlet JVM GC in order to be recycled in any other class loaded by the AppClassLoader JVM GC can not be deleted from the memory of the destruction.

Because the Level class is WebSphere Application Server JRE core system classes, present in the core library core.jar file in the JRE, is a top class JVM ClassLoader loader to be loaded, that is not part of the class Level.class application class loader AppClassLoader.

When the application is unloaded or stopped, Level.class JVM is loaded by the system, so Level.class will not be recovered, then it references CUSTOMLEVEL instance variables and their corresponding class LeakServlet $ 1 will not be recovered resulting AppClassLoader JVM object can not be recovered, which ultimately lead to the application of all the Class class (Class MetaData attribute descriptions) can not be carried out JVM memory as garbage collection.

When the application is restarted, will be the newly created AppClassLoader to reload all of the Class class, so at this time in memory, there exists a class of multisection copies of the same Class.

This form of the notorious class loader ClassLoader memory leak problem.

blog comments powered by Disqus


  • Java program in the "memory leak" problem 2010-07-20

    Transfer from: Soar Abstract: Java's memory management system from the beginning with a discussion of the Java process memory leak cause of the problem, citing a typical memory leak probl

  • Class loader - the memory leak problem of 2 2010-07-29

    Serious warning: If there is any application other than from a reference cited by the J2EE application itself class loader loads the class and class instance object, then ClassLoader class loader memory leak problem arises. ClassLoader class loader memory

  • Java memory leak problem analysis 2010-03-29

    <! - Info --><!-- div> </ div> <div> <ul> <img src = " "/> <p> <a href=""> information first time </ a> </ p> </ ul> <ul

  • Java memory leak problem analysis (change) 2010-03-28

    People talking about memory leaks, of course, for c / c + +, this should be the long-standing problems, but many more Java staff also need to discuss this issue, I write a summary here, we want to have some reference value. Generous concept of memory leak

  • Browser memory leak problem tracking and resolution 2010-09-20

    Browser memory leak problem tracking and resolution prevailed before stored in Ajax, browser memory leaks is not a big problem, because they were all jump through the page and Shuaxin Laijinxingyu Jiaohu server side and they are now not the same, many app

  • flex memory leak problem 2010-07-12

    Flex memory leaks Transfer from: Article 2 FLEX memory optimization techniques collection type: reproduced FLEX memory optimization principles released 1. Is deleted all references to obje

  • Javascript memory leak problem 2009-07-03

    Memory leak, that is, memory can not be configured correctly, the memory can not be timely and effective recovery, he will lead the implementation of efficient procedures for the implementation of the failure of even lower. The field in the browser, most

  • tomcat memory leak problem (quoted from "arbitrarily paste") 2010-03-29

    1, linux, under simple, in the bin found, vi look, followed by annotations added after the sentence: JAVA_OPTS = '-Xms256m-Xmx256m' 256 is an example, you can write the physical memory of 1024 or even 2048, but the individual prop ...

  • Java memory leak in the 2010-12-08

    1 Introduction An important advantage of Java is through the garbage collector GC (Garbage Collection) automatically manages the recovery of memory, the programmer does not need to release the memory by calling the function. Therefore, many programmers th

iOS 开发

Android 开发

Python 开发



PHP 开发

Ruby 开发






Javascript 开发

.NET 开发



Copyright (C), All Rights Reserved. 版权所有 黔ICP备15002463号-1

processed in 0.181 (s). 14 q(s)