我有以下代码生成(有意地)一个PermGen的java.lang.OutOfMemoryError
:标志为PermGen的工作不正常:-XX:+ CMSClassUnloadingEnabled和-XX:+ CMSPermGenSweepingEnabled
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,至少可以看到部分改进。但这种情况并非如此。
问题:我误解了这些标志的含义吗?你能详细说明是不是这种情况?否则,有什么建议?
N.B.的java -version
输出是:
Java版本 “1.7.0_95”
OpenJDK的运行时环境(2.6.4的IcedTea)(7u95-2.6.4-3)
OpenJDK的64位服务器VM (构建24.95-b01,混合模式)
你能否修改你的测试用例,使你的'DynamicClassLoader'实例在整个测试持续时间内都保持不变? AFAIK,所有类加载器保留对它们加载的所有类的引用。除非你的类加载器被GC化了,否则你的类不能被GC化。 – omajid
@omajid谢谢。你打了指甲。 :)。请将其作为回复发布,以便接受它。 – artaxerxe