PDA

View Full Version : non-heap creeping up?


robbio
12-06-2011, 14:45
http://java-monitor.com/postedimages/146fae22-8995-4a2c-941f-a1bd982a143c.png

Hi,

I am a bit surprised to see non-heap uasage creeping up when doing several deployments in Tomcat. Anybody who knows what is going on?

Rob.

kjkoster
12-06-2011, 21:16
Dear Rob,

This is typical behaviour for applications that do not close all of their resources when stopping. Are you sure that you are cleaning up everything you start? This can be quite insidious. I had quite a bit of Googling to do to be able to stop logback for an application I maintain and I still don't know how to properly close Apache ActiveMQ down for redeployment.

Tomcat now ships with code that helps you track down redeployment leaks such as the one you suspect. Have a look at http://java-monitor.com/forum/showthread.php?t=818

Let us know what you find.

robbio
13-06-2011, 10:16
I am using tomcat 7 and have already been cleaning up, great feauture indeed!

But why is this related to non-heap? From the java docs: "The non-heap memory includes the method area and memory required for the internal processing or optimization for the Java virtual machine. It stores per-class structures such as a runtime constant pool, field and method data, and the code for methods and constructors."

So what happens? Any idea?

guus
13-06-2011, 15:55
The generic problem is described by Frank Kieviet in one of his blogposts on the subject:

Application servers such as Glassfish allow you to write an application (.ear, .war, etc) and deploy this application with other applications on this application server. Should you feel the need to make a change to your application, you can simply make the change in your source code, compile the source, and redeploy the application without affecting the other still running applications in the application server: you don't need to restart the application server. This mechanism works fine on Glassfish and other application servers (e.g. Java CAPS Integration Server).
The way that this works is that each application is loaded using its own classloader. Simply put, a classloader is a special class that loads .class files from jar files. When you undeploy the application, the classloader is discarded and it and all the classes that it loaded, should be garbage collected sooner or later.
Somehow, something may hold on to the classloader however, and prevent it from being garbage collected. And that's what's causing the java.lang.OutOfMemoryError: PermGen space exception.


He provides a lot of background on issues like this. The quote above was taken from this blogpost: http://blogs.oracle.com/fkieviet/entry/classloader_leaks_the_dreaded_java

clintgerdel
14-06-2011, 08:09
Hi Rob,

May I ask few questions and to clarify all. Are you sure you have clean all before you start?

robbio
14-06-2011, 08:13
Holy crap! Bugs have two categories: "Ah, ofcourse!" and "O, shit!". This one falls into the later. Thanks for the explanation Guus!

I will start cleaning up any static reference I have declared my self, that will help reduce the problem, as I know that they are quite large objects. I hope I do not have to dig through all classes to search for classes loaded outside the AppClassLoader...

robbio
14-06-2011, 08:17
@clintgerdel
I perform a redeploy and through a ServletContextListener I clean up all threads and other resources on closingdown of the application. Works sweet. The answer of Guus explains probably what is really happening: classloaders holding on to objects and therefor class-data (and more) can not be garbage collected...