私は(意図的に)を生成し、次のコードを持っている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のランタイム環境(IcedTeaの2.6.4)(7u95-2.6.4-3)
OpenJDKの64ビットサーバーVM (ビルド24.95-b01、混合モード)
テストケースを変更して、「DynamicClassLoader」のインスタンスがテスト期間全体にわたって保持されないようにすることはできますか? AFAIK、すべてのクラスローダーは、ロードするすべてのクラスへの参照を保持します。あなたのクラスローダがGCされない限り、あなたのクラスはGCできません。おかげさまで、 – omajid
あなたは爪を打つ。 :)。それを受け入れるために応答として投稿してください。 – artaxerxe