Je le code suivant qui génère (intentionnellement) un PermGen java.lang.OutOfMemoryError
:Drapeaux pour PermGen ne fonctionne pas comme prévu: -XX: + CMSClassUnloadingEnabled et -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);
}
}
}
J'exécuter ce code en Java 7 Comme prévu, il obtient java.lang.OutOfMemoryError: PermGen space
erreur. Lorsque je tente de lancer ce programme avec les drapeaux mentionnés comme suit:
java -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled -jar target/permgen.jar
, je reçois toujours la même erreur, à exactement au même point que quand je le lance sans drapeaux. Je m'attendais à ce que si je mets ces drapeaux, sinon un rafraîchissement total de PermGen se produirait, au moins une amélioration partielle serait vu. Mais ce n'est pas le cas.
Question: Ai-je mal compris la signification de ces drapeaux? Pouvez-vous détailler si c'est le cas, s'il vous plaît? Sinon, des suggestions?
N.B. Sortie de java -version
est:
java version "1.7.0_95"
OpenJDK Runtime Environment (IcedTea 2.6.4) (7u95-2.6.4-3)
OpenJDK 64 bits serveur VM (build 24.95-b01, mode mixte)
Pouvez-vous modifier votre cas de test afin que votre instance de 'DynamicClassLoader' ne soit pas conservée pendant toute la durée du test? AFAIK, tous les classloaders conservent une référence à toutes les classes qu'ils chargent. Sauf si votre classloader est GC'ed, vos classes ne peuvent pas être GC'ed. – omajid
@omajid Merci. Tu frappes l'ongle. :) Veuillez le poster comme réponse afin de l'accepter. – artaxerxe