简体   繁体   English

JDK1.7 ClassLoader内存泄漏

[英]JDK1.7 ClassLoader Memory Leak

I have child-first UrlClassLoader to load jar file dynamically. 我有孩子优先的UrlClassLoader来动态加载jar文件。 Then I do a reflection to invoke a method within loaded jar file. 然后我做一个反射来调用加载的jar文件中的方法。 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. 基本上,我尝试做的是在循环语句中加载和卸载jar。 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(); 当我在JDK1.6下运行此代码时,没有classLoader.close(); statement, that code runs perfectly. 声明,该代码运行完美。 But when I turn into JDK1.7, sometimes I get java.lang.OutOfMemoryError: PermGen space error. 但是当我转向JDK1.7时,有时我会得到java.lang.OutOfMemoryError: PermGen space错误。 Unfortunately it occurs in inconsistent manner. 不幸的是,它以不一致的方式发生。

The easiest way to confirm where the leak comes from is to use a profiler to monitor the memory usage. 确认泄漏源自哪里的最简单方法是使用分析器来监控内存使用情况。 Try JProfiler, or VisualVM. 试试JProfiler或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. 它将使您能够精确定位泄漏的确切位置,并为您提供有关是否以及如何修复泄漏的线索。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM