Skip navigation.

exploreopera

| Help

Sign up | Help

Notes to self

Articles on development, software and the life that follows.

Posts tagged with "permgen"

Return of the PermGen

,

This appears to be the third installment in the saga of my PermGen problems.

For good measure, here are the previous posts:


The newsflash this time is that I stumbled upon some guy Thompson's blog post about this very problem - by itself nothing new; concluding by recommending a JVM with infinite perm-space (BEA or IBM).

The interesting part, however, is stoney's comment where he links to two posts on a blog by Frank Kieviet.

The first of Franks posts is concerned with what the PermGen error is really all about, namely how these leaks in the reloading classloaders in our application servers happen. His second post is a bit more involved and shows how you can use new profiling tools in Java 6 to track down classloader leaks.

So the good news is that we now have the knowledge and tools required to kill this bug.
The bad news is that we've also learned that walking the walk will probably be a lot tougher than talking the talk.

We have to scrutinize our dependency tree, and think really, really, REALLY hard before we put a jar in our servers indorsed directory.

In fact, I think I'll try an experiment tomorrow (today, actually, after I've slept) where I strip down a Tomcat instance (JBoss is probably too intertwined with itself to really strip down) and create some web applications who's only runtime dependencies are the servlet-api and the JRE!

I should really think that classloader leaks are really hard to create with something as simple as the servlet-api, and if you use your JRE with care, then it should damn well be possible to avoid classloader leaks with that dependency as well.

Man, I'm really excited about the idea that there's actually hope for us lay-coders to actually rid ourselves of this nasty ghost-bug-thing/issue.

I'll be sure to report back when I've done some experiments with this new knowledge!

PermGen Strikes Back!

,

Bugger, bugger, bugger!

Just as I thought that the issue with the PermGen OutOfMemoryError was over, it turns out: it's not.

Here's why: by setting the -XX:MaxPermSize=128m, I was only postponing the eventual death of my app server. This postponing was apparently so good, that I didn't incounter the PermGen issue during my, ahem, "tests".

In fact, my "test" was not only manual, it was also naïve. What I did was to run the app server without the GC tuning parameters, and make redeployments until it crashed. Turns out I could make 5 redeployments with an app called Payout (named after my current project). Then I applied the parameters and redeployed again and again until I felt confident it worked. Apparently, I felt confident after 10 redeployments.

My failure was that I didn't do any actual measuring of the state of the memory in the JVM. :clown:

Nervous sysadmin

My sysadmin contacted me today and said that he was worried that the memory usage pattern hadn't changed significantly. The JVM was still, slowly but surely, eating up all its memory. I pointet out that the MaxPermSize had been increased, and the GC probably didn't bother to reclaim memory because there was still plenty of it available. My rationale was, that once the JVM got closer to the max, it would start to do more garbage collection.

And then, I started to feel like testing my claims.

I wrote a small web application that used the MemoryMXBean to plot the NonHeap memory stats to an array list every minute, and then print the list, CSV formattet, on a JSP file. I then followed the memory usage as I start to redeploy again and a again, to see what would happen when I reached the max. As you figured, I got PermGens.
Then I snatched the memory statistics from my little plotter app, and importedd it into Excel to generate this graph:


What have we learned?

Two things:
  1. The PermGen issue is harder to crack than I first thought.
  2. One should properly test one's claims before bragging about it on blogs and dzone and whatnot.

So I guess it's back to the drawing board! :furious:

Good Riddance, PermGen OutOfMemoryError !

, , , ...

<edit>
Before thinking "yay! a fix for my problem!", read this: http://my.opera.com/karmazilla/blog/2007/03/15/permgen-strikes-back

The rest of this article has been left untouched.
</edit>

I did it!

Yes, lads & lasses! If you've been annoyed with having JBoss or Tomcat die with an OutOfMemoryError every fifth time you redeploy your beloved brainchild of a web application, then this is your lucky day! Because I found a fix! It's true! Yay! ....!!!!!11one (can you tell this has been a pain to me?)

Boring but Serious Theory and Hypothesis part:
The "PermGen" error happens, when the Java virtual machine runs out of memory in the permanent generation. Recall that Java has a generational garbage collector, with four generations: eden, young, old and permanent.

In the eden generation, objects are very short lived and garbage collection is swift and often.

The young generation consists of objects that survived the eden generation (or was pushed down to young because the eden generation was full at the time of allocation), garbage collection in the young generation is less frequent but still happens at quite regular intervals (provided that your application actually does something and allocates objects every now and then).

The old generation, well, you figured it. It contains objects that survived the young generation, or have been pushed down, and garbage collection is even less infrequent but can still happen.

And finally, the permanent generation. This is for objects that the virtual machine has decided to endorse with eternal life - which is precicely the core of the problem. Objects in the permanent generation are never garbage collected; that is, under normal circumstances when the jvm is started with normal command line parameters.

So what happens when you redeploy your web application is, that your WAR file is unpacked and its class files loaded into the jvm. And here's the thing: almost always ends up in the permanent generation... Because, seriously, who wants to garbage collect their classes?!? Well, apparently application servers do, and here's how we make that happen;

PermGen, The Fix:
The standard garbage collector can't collect in the permanent generation, but the concurrent collector can. So the first thing we need to do is to make sure that the jvm uses the concurrent garbage collector. This is done by putting this:
-XX:+UseConcMarkSweepGC

In java's command line arguments. But this is not enough. We must also specifically tell it to collect in the permanent generation, and this is done with this command line argument:
-XX:+CMSPermGenSweepingEnabled

Good, now the concurrent collector will take the permantent generation under its wings. But wait! Classes are special, and the jvm is reluctant to let go of them, so we must also explicitly allow classes to be unloaded:
-XX:+CMSClassUnloadingEnabled

Now we're certain that the permanent generation will be properly cleaned. But this raises another issue: what if the jvm unloads classes that might still be needed? I imagine it can be hard for a collector to tell whether or not a class might still be needed with the amount of reflection that goes on in an application server. Therefor, we might want to tweak the amount of memory allocated for the permanent generation, and this is done with this command line parameter:
-XX:MaxPermSize=128m

Which will set the maximum size of our permanent generation to 128 megabytes - tweak it to fit your needs.

With these parameters properly applied to the jvm that runs your application server, your chances of running into a PermGen OutOfMemoryError will be considerably lessened.

Take care!
August 2008
MTWTFSS
July 2008September 2008
123
45678910
11121314151617
18192021222324
25262728293031