码迷,mamicode.com
首页 > 其他好文 > 详细

类加载器泄露学习(二)—— Classloader leaks II – Find and work around unwanted references

时间:2015-12-20 10:29:38      阅读:278      评论:0      收藏:0      [点我收藏+]

标签:

This time we will discuss different reasons for leaks, look at an example of a leak in a third party library, and see how we can fix that leak by a workaround.

Different reasons for ClassLoader leaks

In order to know what you should be looking for in your heapdump analysis, we could categorize ClassLoader leaks into three different types. In the end, they are all just variants of the first one.

    1. References from outside your webapp – that is from the application server or the JDK classes – to either the ClassLoader itself or one of the classes it has loaded (which in turn has a reference to the ClassLoader).
    2. Threads running inside your webapp. If you spawn new threads from within your web application that may not terminate, they are likely to prevent your ClassLoader from being garbage collected. This can happen even if the thread does not use any of the classes loaded by your webapps ClassLoader. This is because threads have a context classloader, to which there is a reference (contextClassLoader) in thejava.lang.Thread class. More about this in the next post.
    3. ThreadLocals with values whose class is loaded in your webapp. If you useThreadLocals in your webapp, you need to explicitly clear all ThreadLocals whenever the webapp closes down. This is because a) the application server uses a thread pool, which means that the thread will outlive your webapp instance and b)ThreadLocal values are actually stored in the java.lang.Thread object. Therefore, this is just a variation of 1. 
      (Note: This may be the case most likely created by yourself, but also exists in third party libraries

Example of reference from outside your application

When trying to hunt down a ClassLoader leak in our web application, I created a little JSP page in which I looped through all the third party JARs of our application. I tried to load every single class that was found in a custom ClassLoader, added a ZombieMarker to the ClassLoader (see previous post) and then disposed the ClassLoader. I ran the JSP page over and over again until I got a java.lang.OutOfMemoryError: PermGen space. That is, I was able to trigger ClassLoader leaks just by loading classes from our third party libraries… 技术分享It actually turned out to be more than one of them, that triggered this behaviour.

Here a MAT trace for one of them:
技术分享
(In this picture, it’s not obvious where our ClassLoader is. The custom ClassLoader was an anonymous inner class in my JSP, so it’s the second entry with the strange class name ending with $1.)

At first glance, it may seem like this is type 2 above, with a running thread. This is not the case however, since the thread itself is not the GC root (not at the bottom level). In fact, there is a Thread involved, but it is not running.

 

Rather we can see that what keeps our ClassLoader from being garbage collected is a reference from outside the webapp (java.lang.*) to an instance of com.sun.media.jai.codec.TempFileCleanupThread, which in turn is loaded by our ClassLoader. From the names of the referenced and referencing (java.lang.ApplicationShutdownHook) classes, I suspected that a JVM shutdown hook was added by some Java Advanced Imaging (JAI) class when it was loaded.

理解:我们的类加载器不能被GC的原因:一个外部引用指向了一个TempFileThread实例,而这个实例是被我们的类加载器所加载的。

The com.sun.media.jai.codec.TempFileCleanupThread class is in the Codec part of JAI; version 1.1.2_01 in our case. The sources can be found in the official SVN repo (1.1.2_01 tag). As you can see, TempFileCleanupThread.java class is not in that list. That is because someone thought is was a great idea to put it as a package protected class inFileCacheSeekableStream.java.

There we can also find the source of the leak.

类加载器泄露学习(二)—— Classloader leaks II – Find and work around unwanted references

标签:

原文地址:http://www.cnblogs.com/Guoyutian/p/5060316.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!