2016-08-22 19 views
1

私はメタスペースOOMをシミュレートしたいです。 、それはjvisualvmに示されている1437に達したときにロードされたクラスの数ストップが増加し、かつ使用メタスペースの大きさが低かったことを奇妙だ、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は取得されません。

このジョブを実行するには、分離されたクラスローダーが必要です。もう1つの選択肢は、cglibまたはasmライブラリで、飛行中にクラスを生成することです。

またloadClassはない正規のしかしバイナリクラス名を受け入れます。

+0

私はClassLoaderの新しい人です。カスタマイズされたClassLoaderについての例はありますか?孤立したクラスローダーを作成する方法を意味しますか? – expoter

+0

@expoter隔離されたクラスローダーに関する基本的なハウツーがあります。http://blog.markturansky.com/archives/21 – vsminkov

+0

@expoterしかし、私はクラスを生成する方が簡単だと思います。 cglibエンハンサークラスを見てください。 – vsminkov

関連する問題