среда, 1 августа 2012 г.

memory: permgen

    Утилита для загрузки байт-кода:

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class ClassLoaderUtil {

    public static byte[] loadByteCode(Class loader, String className) 
                                                                           throws IOException {
        String fileName = "/" 
              + className.replaceAll("\\.", "/") + ".class";
        InputStream is = loader.getResourceAsStream(fileName);
        ByteArrayOutputStream buffer 
              = new ByteArrayOutputStream(4096);
        byte[] buff = new byte[1024];
        int i;
        while ((i = is.read(buff)) >= 0) {
            buffer.write(buff, 0, i);
        }

        return buffer.toByteArray();
    }
}

АНТИПАТТЕРН: Паблик Морозов
    Наш класс-лоадер:
public class MyClassLoader extends ClassLoader {
    public MyClassLoader() {
        super();
    }

    public Class<?> _defineClass(String name, 
                                 byte[] byteCodes) {
        return super.defineClass(
                     name, byteCodes, 0, byteCodes.length);
    }
}

    Стараемся исчерпать память в PermGen:
public class PermGenQuiz0 {

    public static void main(String[] args) throws Exception {
        Class<?> clazz = PermGenQuiz0.class;
        byte[] buffer = ClassLoaderUtil.loadByteCode(clazz, clazz.getName()) ;

        MyClassLoader loader = new MyClassLoader();
        for (long index = 0; index < Long.MAX_VALUE; index++) {
            String newClassName = 
                   "_" + String.format("%0" 
                   + (clazz.getSimpleName().length() - 1) + "d", index);
            byte[] newClassData = new String(buffer, "latin1")
                    .replaceAll(clazz.getSimpleName(), newClassName)
                    .getBytes("latin1");
//                loader = new MyClassLoader();
            loader._defineClass(
                    clazz.getName()
                    .replace(clazz.getSimpleName(), newClassName),
                    newClassData);
        }
    }
}
>> java.lang.OutOfMemoryError: PermGen space
но если раскомментировать строку, то память в PermGen - не исчерпывается и цикл работает столетиями.