Tuesday, April 07, 2009

java.lang.OutOfMemoryError: PermGen space KILLER

When did I see this happen?

I seem to have seen this in 2 different places with in BPEL world so far.

Firstly when I try to use the automated deployment process while deploying to System Test or Use Acceptance Test (UAT) and even in pre-prod some times. I have this whole bunch of about 30+ bpel processes to deploy and have a automated deployment process to do this. In random order in the middle of deployment you get this crap.

Secondly I have even seen this in Development environment, while deploying BPEL process from JDeveloper.

I have never seen this happen any other time at least in the scenarios that I have worked in.

Where do you see this?

If I take this second one first, I mean JDeveloper deployment in DEV, then it is in the JDeveloper logging window.

Now to the first scenario is a bit of a pain. You have a deployment running and all of a sudden the deployment fails. Time to dig into the opmn log file and find these words there.
"java.lang.OutOfMemoryError: PermGen space"

What the hell is PermGen space?

First of all it is NOT PermGem space but it is Perm Gen space.
PermGen stands for Permanent Generation.

How the hell is this related to BPEL?

The answer is both No and Yes.

Why NO?

This weired error is not a BPEL error but a java JVM memory error.

Why YES?

You see this crap come up while deploying BPEL.

So what is the background of PermGen Error?

Well let us dig into java. JVM has this memory called virtual memory. This is the memory that JVM uses to work with what ever it has in hand.
But JVM has 3 different space of it.
The Young, Tenured and Perm.

All the objects that get created are first stored in Young Generation. If the objects survive long enough from garbage collector they get transferred to Tenured Generation.

Now Permanent Generation is special. When there is no space left in Perm you see this error.

So what does Perm Gen contain?

Permanent Generation is special as it contains class definitions.
Objects are in Young and Tenured Generation.

Basically it contains
  • Basic fields of java class
  • Methods of a class (including the bytecodes)
  • Names of the classes
  • Constant pool information
  • Object arrays and type arrays associated with a class
  • Internal objects created by the JVM (java/lang/Object or java/lang/exception for instance)
  • Information used for optimization by the compilers (JITs)
There are a few more pieces in there but this is most of it.

So what causes Perm Gen?

As you are loading BPEL through some ANT task.
ANT runs the java stuff to load BPEL.

The class loader that loads the BPEL fills up the Permanent Generation with the class details of all the classes that you have loaded.

What is the default PermGen?

The default max permanent generation size is 64M, not quite enough.

What is recommended?

1024 is recommended.

How to control this?

Use the following with the command line
-XX:MaxPermSize=1024m

What does
-Xms and -Xmx do to PermGen?

These 2 parameters does nothing to change the Perm Gen space setup by JVM.
You just do want to default Max Perm Gen space to 64 M.

Is this the final solution?

Not really, if you keep loading loads of new processes or huge number of classes this might delay your Out Of Memory Error but will not fix it.

The only solution?

The only solution is to bounce the server once you see this error.

Where else?

This is a general issue faced by all sun java based servers. When huge number if class are loaded as part of an application, this error is expected.

Related Links I liked

http://blogs.sun.com/jonthecollector/entry/presenting_the_permanent_generation
http://forums.oracle.com/forums/thread.jspa?messageID=3344909&#3344909
http://www.jroller.com/agileanswers/entry/preventing_java_s_java_lang

2 comments:

Anonymous said...

seriously 1G of perm gen memory need is ridiculous and a sign that the EE server desiginers have totally lost the plot. Why are we using this bloated crap?

Kalidass Mookkaiah said...

This figure seems to work out in large enterprise projects with 40+ components. For larger systems this should be higher and yes for smaller systems this should be lower. This is case by case basis choice.
If you suggest that this is bloated, can you suggest under which context? Do you have a reason to think so?