关闭

采用类加载器加载多次类,perm区满了,发生FGC

标签: stringexceptionclassloaderbyteserviceclass
1149人阅读 评论(0) 收藏 举报
分类:
1. 编写的自定义类加载器
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

public class MyClassloader extends ClassLoader {

    public Class<?> findClass(String name) {
        byte[] data = loadClassData(name);
        return defineClass(name, data, 0, data.length);
    }

    private byte[] loadClassData(String name) {

        FileInputStream fis = null;
        byte[] data = null;
        try {
            fis = new FileInputStream(new File(getFinalPath(name)));
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int ch = 0;
            while ((ch = fis.read()) != -1) {
                baos.write(ch);
            }
            data = baos.toByteArray();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }

    private String getFinalPath(String name) {
        String finalPath = "";
        String path = System.getProperty("user.dir");
        String[] nameStrings = name.split("\\.");
        String tempStr = "";
        for (String str : nameStrings) {
            tempStr = tempStr + str + File.separatorChar;
        }
        tempStr = tempStr.substring(0, tempStr.lastIndexOf(File.separatorChar));
        finalPath = path + File.separator + tempStr + ".class";
        return finalPath;
    }

}


2. 编写的发生GC的程序

public class GcDemo {

    private final static String str = "sdfskfjskfjskfjskfjskdjf";
    static{
        str.intern(); // 会进入Perm区
    }

    public static void main(String[] args) throws Exception {
        MemoryObject object = new MemoryObject(1024 * 1024);
        for (int i = 0; i < 2; i++) {
            happenMinorGC(11);
            Thread.sleep(10000);
        }
    }

    private static void happenMinorGC(int happenMinorGCIndex) throws Exception {
        for (int i = 0; i < happenMinorGCIndex; i++) {
            if (i == happenMinorGCIndex - 1) {
                Thread.sleep(10000);
                System.out.println("minor gc should happen");
            }
            new MemoryObject(1024 * 1024);
        }
    }
}

class MemoryObject {

    private byte[] bytes;

    public MemoryObject(int objectSize) {
        this.bytes = new byte[objectSize];
    }
}

3. 测试Perm区满的时候,是否发生FGC?

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MyApp {
   public static void main(String[] args) throws InterruptedException,InstantiationException, IllegalAccessException {

        // local
        int size = 100;
        ExecutorService es = Executors.newFixedThreadPool(size);

        for(int i=0 ;i< size;i++){
            es.execute(new Runnable(){

                @Override
                public void run() {
                    for(int i=0;i<20000;i++) {
                        MyClassloader loader = new MyClassloader();
                        Class<?> objClass = loader.findClass("GcDemo");
                        Object service;
                        try {
                            service = objClass.newInstance();
                            System.out.println(service.getClass());
                            System.out.println(objClass.getName());
                            System.out.println(objClass.getClassLoader());
                            System.out.println(service);
                        } catch (InstantiationException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (IllegalAccessException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }

                        System.out.println(GcDemo.class.getClassLoader());
                        Thread.yield();
                     }
                }
            });
        }
        es.shutdown();
    }

}


结论: 当perm区满的时候是会发生FGC的。


参考: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:46098次
    • 积分:694
    • 等级:
    • 排名:千里之外
    • 原创:24篇
    • 转载:9篇
    • 译文:0篇
    • 评论:6条
    最新评论