Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JDK1.7 ClassLoader Memory Leak

I have child-first UrlClassLoader to load jar file dynamically. Then I do a reflection to invoke a method within loaded jar file. Once it is finished, I prefer to unload the classloader. Then I try to do some stress test code to make sure my code run smoothly. Basically, what I try to do is load and unload jar within looping statement. Here is my code:

    for (int i = 0; i < 1000; i++) {
        //Just to show the progress
        System.out.println("LOAD NUMBER : " + i);

        ChildFirstURLClassLoader classLoader = null;
        try {
            File file = new File("C:\\library.jar");
            String classToLoad = "com.test.MyClass";
            URL jarUrl = new URL("file:" + file.getAbsolutePath());

            classLoader = new ChildFirstURLClassLoader(new URL[] {jarUrl}, null);
            Class<?> loadedClass = classLoader.loadClass(classToLoad);
            Method method = loadedClass.getDeclaredMethod("execute",
                    new Class[] {});

            ClassLoader currCl= Thread.currentThread().getContextClassLoader();
            Thread.currentThread().setContextClassLoader(classLoader);
            method.invoke(null);
            Thread.currentThread().setContextClassLoader(currCl);

            method = null;
            loadedClass = null;
        } finally {
            if (classLoader != null) {
                classLoader.close();
                classLoader = null;
            }
        }
    }

When I'm running this code under JDK1.6, without classLoader.close(); statement, that code runs perfectly. But when I turn into JDK1.7, sometimes I get java.lang.OutOfMemoryError: PermGen space error. Unfortunately it occurs in inconsistent manner.

like image 703
user1915918 Avatar asked Dec 19 '12 13:12

user1915918


People also ask

What is Classloader leak?

To leak a classloader it's enough to leave a reference to any object, created from a class, loaded by that classloader. Even if that object seems completely harmless (e.g. doesn't have a single field), it will still hold on to its classloader and all the application state.

How do you fix a memory leak in Java?

Use reference objects to avoid memory leaks Using the java. lang. ref package, you can work with the garbage collector in your program. This allows you to avoid directly referencing objects and use special reference objects that the garbage collector easily clears.


1 Answers

The easiest way to confirm where the leak comes from is to use a profiler to monitor the memory usage. Try JProfiler, or VisualVM. It will enable you to pinpoint the exact location of the leak, and also give you clues as to whether and how you can fix it.

like image 126
matt.nguyen Avatar answered Sep 20 '22 03:09

matt.nguyen