2 votes

Comment simuler OutOfMemoryError : Metaspace

J'aimerais savoir comment provoquer une OutOfMemoryError : Metaspace par vous-même ? Est-il possible de charger un grand nombre de classes et de les faire rester en mémoire pendant un long moment.

1voto

Schidu Luca Points 3035

Il suffit d'ajouter du texte à un StringBuilder jusqu'à ce que vous obteniez OutOfMemoryError

StringBuilder s = new StringBuilder();

while (true) {
    s.append("dummy");
}

Vous pouvez également ajouter une classe fictive à un fichier de type List ou un Set mais la création de nouvelles instances prend plus de temps et vous devrez attendre un certain temps avant d'obtenir des résultats. OutOfMemoryError .

Le coût en temps amorti de l'insertion dans une liste Array fera également la différence.

Mise à jour de

Par défaut, Java 8 dispose d'une taille maximale illimitée pour Metaspace, donc tant que vous ne fixez pas la limite en utilisant l'attribut MaxMetaspaceSize l'erreur ne doit pas être déclenchée.

0voto

Vaisakh PS Points 737

Pour créer OutOfMemoryError: Metaspace utiliser le javassist.ClassPool bibliothèque. L'exemple ci-dessous créera la bibliothèque Metaspace erreur.

import javassist.ClassPool;

public class OutOfMemoryErrorMetaspace {

    //ClassPool objects hold all the CtClasses.
    static ClassPool classPool = ClassPool.getDefault();

    public static void main(String[] args) throws Exception {
           for (int i = 0; i < 1000000; i++) {
                  //makeClass method - Creates a new class (or interface) from the given class file.
                  Class clas = classPool.makeClass(
                               i + " outofmemory.OutOfMemoryErrorMetaspace ").toClass();
                  //Print name of class loaded
                  System.out.println(clas.getName());
           }
    }
}

0voto

pero_hero Points 1912

Afin de simuler java.lang.OutOfMemoryError: Metaspace vous devez charger un grand nombre de classes différentes.

Tout d'abord, les paramètres suivants du méta-espace doivent être définis :

-XX:MaxMetaspaceSize=10m
-XX:MetaspaceSize=2M
-XX:MaxMetaspaceFreeRatio=1
-XX:MaxMetaspaceExpansion=1K
-XX:MinMetaspaceFreeRatio=1
-XX:InitialBootClassLoaderMetaspaceSize=2M

Ensuite, le code suivant permet au classloader de charger un grand nombre de classes différentes. Ceci est accompli en prenant le bytecode compilé d'une classe mypackage.Myclass0 et d'ajuster pour créer itérativement de nouvelles classes en changeant le nom de la classe et en ajustant la longueur du nom de la classe :

    public static void main(String[] args) throws Exception {
        String clazzBase64 ="yv66vgAAADcADAEAEm15cGFja2FnZS9NeWNsYXNzMAcAAQEAEGphdmEvbGFuZy9PYmplY3QHAAMBAApTb3VyY2VGaWxlAQANTXljbGFzczAuamF2YQEABjxpbml0PgEAAygpVgwABwAICgAEAAkBAARDb2RlACEAAgAEAAAAAAABAAEABwAIAAEACwAAABEAAQABAAAABSq3AAqxAAAAAAABAAUAAAACAAY=";

        byte[] compiledClazz = Base64.getDecoder().decode(clazzBase64);
        int classNameLength = Integer.valueOf(compiledClazz[12]);

        MyClassLoader myClassLoader = new MyClassLoader(Thread.currentThread().getContextClassLoader());

        for (int i = 0; ; i++) {
            byte[] bytes = String.valueOf(i).getBytes();
            byte[] bytecode = new byte[compiledClazz.length + bytes.length - 1];
            System.arraycopy(compiledClazz, 0, bytecode, 0, 30);
            bytecode[12] = (byte) (classNameLength + bytes.length - 1 & 0xFF);

            System.arraycopy(bytes, 0, bytecode, 30, bytes.length);
            System.arraycopy(compiledClazz, 31, bytecode, 30 + bytes.length, compiledClazz.length - 31);

            String classname = "mypackage.Myclass" + i;
            Class c = myClassLoader.getClass(classname, bytecode);
        }
    }

    public static class MyClassLoader extends ClassLoader {
        public MyClassLoader(ClassLoader parent) {
            super(parent);
        }

        public Class<?> getClass(String name, byte[] code) {
            return defineClass(name, code, 0, code.length);
        }
    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X