2016-08-22 5 views
1

Я хочу симулировать metaspace OOM. Я планирую загрузить класс ClassA различным URLClassLoader, вот код:Почему класс не может быть загружен URLClassLoader?

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!"); 
    } 
} 

Но это странно, что загруженная классы числа стоп увеличивается, когда он достигнет 1437, который показан в jvisualvm, и размер Метапространства используются был низким, хотя цикл for работает миллионы раз. Кажется, что ClassA не загружался каждым новым экземпляром URLClassLoader. Зачем?

ответ

1

Проблема в том, что URLClassLoader является родителем системного загрузчика. И при загрузке он сначала попытается получить класс from parent classloader. Таким образом, класс будет загружен только один раз, и вы не получите metaspace OOM.

Для выполнения этой задачи требуется изолированный загрузчик классов. Другой вариант - генерировать классы на лету с библиотеками cglib или asm.

Также loadClass принимает не канонических но двоичных имен классов.

+0

Я новый парень в ClassLoader, есть ли какой-нибудь пример с настраиваемым ClassLoader? Я имею в виду, как создать изолированный загрузчик классов? – expoter

+0

@expoter есть базовое howto на изолированных загрузчиках классов - http://blog.markturansky.com/archives/21 – vsminkov

+0

@expoter, но я думаю, было бы легче создавать классы. взгляните на класс cglib enhancer. – vsminkov