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

来源:互联网 发布:凤城一路淘宝店 编辑:程序博客网 时间:2024/05/16 07:40
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



原创粉丝点击