Don't let PermGen ruin your weekendDon't let PermGen ruin your weekend

I spent most of Sunday fighting with Tomcat (the application server, not the celebrity newlyweds). That is the last of all ways I would like to spend a day (except, perhaps, with celebrity newlyweds). Java app servers, when they don’t work, make you think seriously whether Java’s abstraction advantage over PHP, or paper and pencil for that matter, is worth it after all.

My problem was that reloading application contexts at databinder.net was causing Tomcat to become unresponsive, jump on the couch, and monopolize the CPU. I took this as a challenge, since the ability to reload individual apps without bringing down the entire server is the only reason I had switched to Tomcat from plain Jetty a few weeks back. Unfortunately for my Sunday, no amount of antiJARLocking / antiResourceLocking-fu produced reliable reloading.

Deciding that Tomcat was a worthless pile of doggie doo, today I tried out Geronimo (previously avoided on account of its terrifying list of useless J2EE features). To my surprise, Geronimo is a joy to install and use. And it’s got Jetty! And configuration pages that don’t appear to be coded for Mosaic! Geronimo is the bomb.

But my crush met with grim reality as I eventually determined that Geronimo suffered the same dreadful reloading problem as Tomcat. So—wait—it’s my code at fault? Bullshit. Then I tried the app server’s 2.0-M1 (?) release, which also failed but finally spat out a useful clue: out of PermGen space. Oh.

Of course I’ve seen this problem before. Our production servers at work have all kinds of memory limits boosted. It just didn’t seem like a problem for lil’ old databinder.net. It’s one of those Java gotchas, where you do everything right according to whatever documentation you can find, yet nothing works. You’re just supposed to know, as I did but had forgotten, that Hibernate or anything else that uses cglib heavily will blow past the standard PermGen limit. (You’d think that app servers would boost the minimum in their own scripts since it’s affected by their reload features.)

I’ve long been planning to write a 101 section for deploying a Databinder application. The only thing holding me back was the lack of a setup that met any minimum standard of simplicity and reliability. Finally with this change and my belated discovery of the lovely Geronimo 1.1, I have some information worth sharing. Coming soon.

In the mean time, don’t forget to eat your -XX:MaxPermSize=128m.

Update: You can increase PermGen, but you’re only postponing inevitable, unpredictable failure. A few months after writing this I gave up on context reloading and Geronimo. Now I’m running separate Jetty contexts in separate JVMs.

Add a comment