Most probably, a lot of Java developers have seen OutOfMemory error  one time or other. However these errors come in different forms and  shapes. The more common is: "Exception in thread "main"  java.lang.OutOfMemoryError: Java heap space" and indicates that the Heap  utilization has exceeded the value set by -Xmx. This is not the only  error message, of this type, however.
One more interesting flavor of the same error message, less common  but hence even more troublesome is: "java.lang.OutOfMemoryError: PermGen  space". Most of the memory profiler tools are unable to detect this  problem, so it is
even more troublesome and therefor - interesting. 
To understand this error message and fix it, we have to remember  that, for optimized, more efficient garbage-collecting Java Heap is  managed in generations - memory segments holding objects of different  ages. Garbage collection algorithms in each generation are different.  Objects are allocated in a generation for younger objects - the Young  Generation, and because of infant mortality most objects die there. When  the young generation fills up it causes a Minor Collection. Assuming  high infant mortality, minor collections are garbage-collected  frequently. Some surviving objects are moved to a Tenured Generation.  When the Tenured Generation needs to be collected there is a Major  Collection that is often much slower because it involves all live  objects. Each generation contains variables of different length of life  and different GC policies are applied to them.
There is a third generation too - Permanent Generation. The permanent  generation is special because it holds meta-data describing user  classes (classes that are not part of the Java language). Examples of  such meta-data are objects describing
classes and methods and they are stored in the Permanent Generation.  Applications with large code-base can quickly fill up this segment of  the heap which will cause java.lang.OutOfMemoryError: PermGen no matter  how high your -Xmx and how much memory you have on the machine.
Sun JVMs allow you to resize the different generations of the heap,  including the permanent generation. On a Sun JVM (1.3.1 and above) you  can configure the initial permanent generation size and the maximum  permanent generation size.
To set a new initial size on Sun JVM use the 
-XX:PermSize=64m option when starting the virtual machine. To set the maximum permanent generation size use 
-XX:MaxPermSize=128m  option. If you set the initial size and maximum size to equal values  you may be able to avoid some full garbage collections that may occur  if/when the permanent generation needs to be resized. The default values  differ from among different versions but for Sun JVMs upper limit is  typically 64MB. 
Some of the default values for Sun JVMs are listed below.
 |  JDK 1.3.1_06  |   Initial Size  |   Maximum Size |  
 |  Client JVM      |   1MB            |    32MB |  
 |  Server JVM      |   1MB            |    64MB |  
 
 |  JDK 1.4.1_01  |   Initial Size  |   Maximum Size |  
 |  Client JVM      |   4MB            |    64MB |  
 |  Server JVM      |   4MB            |    64MB |  
 
 |  JDK 1.4.2  |   Initial Size  |   Maximum Size |  
 |  Client JVM      |   4MB            |    64MB |  
 |  Server JVM      |   16MB           |    64MB |