tags:

views:

160

answers:

6

I am getting PermGen space error on Sun JVM (1.6.0_21-b06) (Ok, it's Oracle :)). Increasing of option -XX:MaxPermGen value does not help. I know that PermGen is a space intended for permanent objects like class metadata. Count of classes in project is not so big ~ 10 000. Before crash jvisualvm shows 57MB as Used PermGen.

I guess that some algorithm occupies all accessible memory. Does someone know examples of algorithms that lead to PermGen overflow ?

UPD. I ask such abstract question, because in the moment I can not use any profiler - code crashes so hard that jvisualvm and eclipse stop to respond. I need than kill java processes from terminal with kill -KILL {process_numer}. I work with bad organized (but commercial) code that has many threads and JMS messaging. Debugging is a mess - I need some idea first where to look.

+2  A: 

It's not so much the algorithm as the implementation. Here's a really dumb way to generate random Strings that fills up PermGen space:

    Random rnd = new Random();
    List<String> interned = new ArrayList<String>();
    for (;;) {
        int length = rnd.nextInt(100);
        StringBuilder builder = new StringBuilder();
        String chars = "abcdefghijklmnopqrstuvwxyz";
        for ( int i = 0; i < length; i++ ) {
            builder.append(chars.charAt(rnd.nextInt(chars.length())));
        }
        interned.add(builder.toString().intern());
    }

In short: interning Strings is one thing that can eat up PermGen memory.

Mark Peters
A: 

Are you using a different garbage collector?

The throughput collector will throw an out-of-memory exception if too much time is being spent doing garbage collection. For example, if the JVM is spending more than 98% of the total time doing garbage collection and is recovering less than 2% of the heap, it will throw an out-of-memory expection. The implementation of this feature has changed in 1.5. The policy is the same but there may be slight differences in behavior due to the new implementation.” ” In the J2SE Platform version 1.5 the throughput collector will be chosen as the garbage collector on server class machines.” http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html

Check some instructions on this page.

tulskiy
+1  A: 

If you use java.lang.reflect.Proxy very intensively, that could eat up your PermGen space as well.

Michael Borgwardt
+1  A: 

Does someone know examples of algorithms that lead to PermGen overflow ?

Yes but what is the point of this? if you want to fix this install a memory profiler tool like jprobe or lambda probe and check where the memory leak is happening, and fix that. Now for the example: There are thousands of ways to exceed perm gen space. I had noticed on a project when we inherited an application where they were using JMS. The jms connections were left open, the application crashed within a few minutes after it got a lot of requests with a similar error like you are getting. Point to note: when we moved to weblogic from jboss (moved to beajrockit) amazingly it fixed itself or atleast took the blow of technical debt. My advice would be irrespective of this, bad code with memory leaks should be fixed first, then tinker with app servers and heap space allocation paramters.

Here is a useful link with some information on the exception you are getting. http://www.jroller.com/agileanswers/entry/preventing_java_s_java_lang

EDIT

This link may be helpfull http://www.precisejava.com/javaperf/j2ee/JMS.htm

sjt
I think in my case your idea about JMS is most prospective. Some messages are sent just before crash.
Nulldevice
The thing about JMS framework is that it is asynchronous, several asynchronous requests can be received, when the jms connection are not closed it can lead to issues. Best of luck.
sjt
+1  A: 

Check out memory analyzer - http://www.eclipse.org/mat/. It is a java dump memory analyzer. It is pretty useful after an unexpected error.

Skarab
A: 

There are two things that are likely to lead to PermGen space issues:

  1. The String.intern(String) method creates Strings in the PermGen heap. If you do a lot of interning and directly (or indirectly) retain references to the interned Strings, you can fill PermGen.

  2. The classloaders creates JVM internal class descriptors and code segments in the PermGen heap. If your application does a lot of dynamic class loading, and the class objects don't get garbage collected, you can fill PermGen.

Hot redeployment of Java webapps relies on dynamic loading and is a common source PermGen problems. The root cause is typically a memory leak that involves a hidden reference from some object to an old classloader. (Tomcat often gets "stick" for this, but the real problem is typically in the webapp that is being redeployed.)

AFAIK, the Proxy case mentioned by @Michael Borgwardt is also a result of the Proxy implementation generating class files and loading them on the fly.

Stephen C