2016-08-22 3 views
1

Ich möchte Metaspace OOM simulieren. Ich plane Klasse laden ClassA von verschiedenen URLClassLoader, hier ist der Code:Warum Klasse kann nicht von URLClassLoader geladen werden?

package classloader; 

import java.io.File; 
import java.net.URL; 
import java.net.URLClassLoader; 
import java.util.ArrayList; 
import java.util.List; 

class ClassA { 
    public void method(String input){} 
} 

public class ClassMetadataLeakSimulator { 
    private final static int NB_ITERATIONS_DEFAULT = 50000; 

    public static void main(String[] args) { 
     System.out.println("Class metadata leak simulator"); 
     int nbIterations = (args != null && args.length == 1) ? Integer.parseInt(args[0]) : NB_ITERATIONS_DEFAULT; 
     try { 
      List<ClassLoader> list = new ArrayList<>(); 
      URL url = new File(".").toURI().toURL(); 
      URL[] urls = new URL[]{url}; 
      System.out.println(url); 
      for (int i = 0; i < nbIterations; i++) { 
       URLClassLoader newClassLoader = new URLClassLoader(urls); 
       list.add(newClassLoader); 
       newClassLoader.loadClass("classloader.ClassA"); 
      } 
     } 
     catch (Throwable any) { 
      System.out.println("ERROR: " + any); 
     } 
     System.out.println("Done!"); 
    } 
} 

Aber, es ist seltsam, dass der geladene Klassen Nummer Anschlag zu erhöhen, wenn es 1437 erreichen, welche in jvisualvm gezeigt wird, und mLokal Größe verwendet wurde, war gering, obwohl die for-Schleife millionenfach gelaufen ist. Es scheint, dass ClassA nicht von jeder neuen URLClassLoader-Instanz geladen wurde. Warum?

Antwort

1

Das Problem ist, dass URLClassLoader durch System Classloader parented ist. Und unter Last wird es zuerst versuchen, die Klasse from parent classloader zu bekommen. Die Klasse wird also nur einmal geladen und Sie erhalten kein Metaspace OOM.

Sie benötigen einen isolierten Klassenlader, um diese Aufgabe zu erledigen. Die andere Option besteht darin, Klassen mit den Bibliotheken cglib oder asm zu generieren.

Auch loadClass akzeptiert nicht kanonische aber binäre Klassennamen.

+0

Ich bin ein neuer Typ in ClassLoader, gibt es ein Beispiel für benutzerdefinierte ClassLoader? Ich meine, wie man einen isolierten Klassenlader erstellt? – expoter

+0

@expoter gibt es ein grundlegendes Howto auf isolierte Classloader - http://blog.markturansky.com/archives/21 – vsminkov

+0

@expoter, aber ich denke, es wäre einfacher, Klassen zu generieren. Werfen Sie einen Blick auf cglib Enhancer-Klasse. – vsminkov

Verwandte Themen