Я следующий код, который генерирует (намеренно) в 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
является:
ява версия "1.7.0_95"
OpenJDK Runtime Environment (IcedTea 2.6.4) (7u95-2.6.4-3)
OpenJDK 64-разрядного сервера VM (сборка 24.95-b01, смешанный режим)
Можете ли вы изменить свой тестовый пример, чтобы ваш экземпляр 'DynamicClassLoader' не поддерживался на протяжении всей продолжительности теста? AFAIK, все загрузчики классов сохраняют ссылку на все классы, которые они загружают. Если ваш загрузчик классов GC'ed, ваши классы не могут быть GC'ed. – omajid
@omajid Спасибо. Вы попали в гвоздь. :). Пожалуйста, отправьте его как ответ, чтобы принять его. – artaxerxe