12
我有孩子第一UrlClassLoader動態加載jar文件。然後我做一個反射來調用加載的jar文件中的一個方法。一旦完成,我寧願卸載類加載器。然後我嘗試做一些壓力測試代碼,以確保我的代碼運行順利。基本上,我試圖做的是在循環語句中加載和卸載jar。這裏是我的代碼:JDK1.7 ClassLoader內存泄漏
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;
}
}
}
當我JDK1.6下運行這段代碼,無需classLoader.close();
聲明,該代碼運行完美。但是當我轉換成JDK1.7時,有時會出現java.lang.OutOfMemoryError: PermGen space
錯誤。不幸的是它以不一致的方式出現。
您可以嘗試設置最大燙髮代碼,以查看這種情況是否發生在更低值的情況下。如果沒有發生,您還可以檢查Java 6的最大值是否相同。 –
你的com.test.MyClass類是做什麼的? Java 7中發生了一些變化,因此掛起的finalize方法可能會阻止類被釋放,也許這就是您在這裏看到的問題。在OutOfMemory上創建堆轉儲,將其加載到MemoryAnalyzer(或類似工具),列出類加載器並搜索對它們的引用。 – mihi
謝謝你彼得和Mihi,我試圖增加最大permgen,但它仍然是一樣的。在Java 6中,我只用64m permgen空間運行沒有問題。實際上,com.test.MyClass通過使用Spring JDBC查詢數據庫。我已經分析了我的堆轉儲,並且看到沒有強類型引用到類加載器中。謝謝大家。 – user1915918