簡體   English   中英

PermGen的標志未按預期運行:-XX:+ CMSClassUnloadingEnabled和-XX:+ CMSPermGenSweepingEnabled

[英]Flags for PermGen not working as expected: -XX:+CMSClassUnloadingEnabled and -XX:+CMSPermGenSweepingEnabled

我有以下代碼(有意地)生成PermGen java.lang.OutOfMemoryError


public class Main {

    public static void main(String[] args) throws InstantiationException, IllegalAccessException, InterruptedException {
        String name = "MyClass";
        DynamicClassLoader cl = new DynamicClassLoader();

        int i = 0;
        while (true) {
            //code for generating the binary for a class to be loaded.
            ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
            cw.visit(Opcodes.V1_7, Opcodes.ACC_PUBLIC, name + ++i, null, "java/lang/Object", null);
            MethodVisitor con = cw.visitMethod(Opcodes.ACC_PUBLIC, "", "()V", null, null);
            con.visitCode();
            con.visitVarInsn(Opcodes.ALOAD, 0);
            con.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "", "()V", false);
            con.visitInsn(Opcodes.RETURN);
            con.visitMaxs(1, 1);
            cw.visitEnd();
            //binary code for class successfully generated

            Class clazz = cl.defineClass(name + i, cw.toByteArray());
            Object o = clazz.newInstance();
            System.out.println(o.getClass().getName());
        }
    }

    private static class DynamicClassLoader extends ClassLoader {
        public Class defineClass(String name, byte[] b) {
            return defineClass(name, b, 0, b.length);
        }
    }
}

我在Java 7中運行此代碼。正如預期的那樣,它得到java.lang.OutOfMemoryError: PermGen space錯誤。 當我嘗試使用上述標志運行該程序時,如下所示:

java -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled -jar target/permgen.jar

,我仍然會收到與沒有標志運行它時完全相同的錯誤。 我希望,如果我放下這些標志,則不會完全刷新PermGen,至少可以看到部分改進。 但這種情況並非如此。

問題 :我是否誤解了這些標志的含義? 請您詳細說明一下嗎? 否則,有什么建議嗎?

注意: java -version輸出是:

Java版本“ 1.7.0_95”

OpenJDK運行時環境(IcedTea 2.6.4)(7u95-2.6.4-3)

OpenJDK 64位服務器VM(內部版本24.95-b01,混合模式)

所有類加載器都對它們加載的所有類保持強大的引用。 在您的示例中,您將繼續重用DynamicClassLoader的單個實例。 反過來,此類加載器保留對所加載的所有類的強引用。 因此,垃圾收集器永遠不會看到它可以收集的未引用對象。

如果您修改測試用例以使用單獨的類加載器,則垃圾收集器應該能夠識別出沒有使用您的類,並且應該回收內存。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM