2016-08-22 7 views
1

메타 공간 OOM을 시뮬레이트하고 싶습니다. 그것은 jvisualvm에 표시하고, metaspace 크기 낮은 사용되는 1,437에 도달하면로드 된 클래스 번호 정지가 증가하는 것은 이상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!"); 
    } 
} 

그러나 : 나는 다른 URLClassLoader의에 의해 클래스 ClassA를로드 할 계획, 여기에 코드입니다 for 루프는 수백만 번 실행됩니다. 새로운 URLClassLoader 인스턴스마다 ClassA가로드되지 않은 것으로 보입니다. 왜?

답변

1

URLClassLoader은 시스템 클래스 로더가 사용하는 것이 문제입니다. 그리고로드시에는 처음에 클래스 from parent classloader을 얻으려고 시도 할 것입니다. 따라서 클래스는 한 번만로드되며 메타 공간 OOM을 얻지 못합니다.

이 작업을 수행하려면 격리 된 클래스 로더가 필요합니다. 다른 옵션은 cglib 또는 asm 라이브러리를 사용하여 클래스를 생성하는 것입니다.

또한 loadClass하지 정규하지만 클래스 이름을 받아들입니다.

+0

저는 ClassLoader의 새로운 사람입니다. 사용자 정의 된 ClassLoader에 대한 예제가 있습니까? 내가 분리 된 클래스 로더를 만드는 방법을 의미합니까? – expoter

+0

@expoter 고립 된 클래스 로더에 기본적인 하우투가있다. http://blog.markturansky.com/archives/21 – vsminkov

+0

@expoter하지만 클래스를 생성하는 것이 더 쉬울 것이라고 생각한다. cglib enhancer 클래스를 살펴보십시오. – vsminkov