简体   繁体   中英

Memory leak in java web application

I have a web application that uses hibernate 3.6.4 and spring 3.2.4 (mvc,tx and security) and is running in tomcat 7. Each time when I deploy a newer version of my app without restarting tomcat, then the memory used by tomcat increases about 50MB.

I created some heap dumps and analysed them with Eclipse Memory Analyser. I found out that each time when I redeployed the app, a new instance of WebappClassLoader was created. But even after I stopped the application with tomcat manager, the WebappClassLoader remains in memory and is not garbage collected. So after each redeploy an additional WebappClassLoader remains in memory and uses about 50MB of memory.

I used the Eclipse Memory Analyser in order to find the reference paths from the WebappClassLoader to the GC roots. In the result I couldn't find any strong references that could prevent the WebappClassLoaders from being garbage collected.

在此输入图像描述

So, what keeps the WebappClassLoaders alive? Where else could I investigate in order to find out, what prevents the WebappClassLoader from the garbage collection?

I thought that there is maybe a blocking finalize() method that prevents the GC from finishing the garbage collection. But how could I check this?

Class loaders are in theory garbage collected when there is not reference to the object instances and class unloading is not necessary, but in practice it seems like to be more problematic.

I would recommend to read this two articles

http://frankkieviet.blogspot.com.au/2006/10/classloader-leaks-dreaded-permgen-space.html

http://frankkieviet.blogspot.com.au/2006/10/how-to-fix-dreaded-permgen-space.html

You can follow the steps presented in Anatomy of a PermGen Memory Leak tutorial too. They are using Java Visual VM but the steps and the things to check should be the same in Eclipse Memory Analizer too. In this presentation you can find the possible causes of such leaks.

Also note that if you don't see any references to WebappClassLoaders it could be that the JVM has plenty of PermGen and is postponing the eviction. You could easily check this by running with a smaller PermGen size and do a couple of redeploys.

I'm not expert in Tomcat and it's re-deployment implementation, but back in the days when we used JBoss, we had quite similar situation. It was due to the fact that PermGen space is not garbage-collected, and every new deployment puts classes in there. So if you are not on Java 8, check if the actual "leak" is not in the permgen space.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM