Почему класс не может быть загружен URLClassLoader?

Я хочу смоделировать метапространство OOM. Я планирую загрузить класс ClassA другим 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. Почему?


person expoter    schedule 22.08.2016    source источник


Ответы (1)


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

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

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

person vsminkov    schedule 22.08.2016
comment
Я новичок в ClassLoader, есть ли какой-нибудь пример настроенного ClassLoader? Я имею в виду, как создать изолированный загрузчик классов? - person expoter; 22.08.2016
comment
@expoter есть базовое руководство по изолированным загрузчикам классов - blog.markturansky.com/archives/21 - person vsminkov; 22.08.2016
comment
@expoter, но я думаю, было бы проще создавать классы. взгляните на класс усилителя cglib. - person vsminkov; 22.08.2016