Sunday, October 25, 2015

How to generate a OutOfMemoryError PERMGEN

Inspired by a very interesting presentation by Pierre-Hugues Charbonneau:

I have partially copied his code to generate a OOM PERMGEN:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.Map;

public class ClassLoaderLeak {
    private static Map leakingMap = new HashMap ();
    public static void main(String[] args) {
 try {
     for (int i = 0; i < 100000; i++) {
  String dummyCLURLString = "file:" + i + ".jar";
  URL[] dummyCLURL = new URL[] { new URL(dummyCLURLString) };
  URLClassLoader urlClassLoader = new URLClassLoader(dummyCLURL);
  Class[] arg1 = new Class[] {Aclass.class}; 
  InvocationHandler arg2 = new InvocationHandler() {
      @Override
      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
   return null;
      }
  };
  Aclass aclass = (Aclass)Proxy.newProxyInstance(urlClassLoader, arg1, arg2);
  leakingMap.put(dummyCLURLString, aclass);
  Thread.sleep(10);
     }
 } catch (Exception e) {
     e.printStackTrace();
 }

    }

}

run it with "java -XX:+HeapDumpOnOutOfMemoryError -XX:MaxPermSize=64m -Xmx256m ClassLoaderLeak

you will see the PermGen space quickly fill up until you get a OOM error

You should see something like
java.lang.OutOfMemoryError: PermGen space  
Dumping heap to java_pid15744.hprof ...
Heap dump file created [154441412 bytes in 1.982 secs]

Now open Eclipse MAT, open the java_pid15744.hprof file and run the Java Basics / Classloader Explorer tool:

You will see several thousands (in my case, 27k) instances of URLClassLoader accumulated in the PERMGEN

No comments: