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

原创 2012年03月21日 10:30:37
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



Jetty:部署到Jetty

Web应用的框架 标准Jetty发布版本能部署标准servlet Spec Web应用和Jetty内部ContextHandler部署描述符,或者两者的一个混合。 Web应用是可部署的动态(servl...

jvm中的新生代Eden和survivor区

聊聊JVM的年轻代 1.为什么会有年轻代 我们先来屡屡,为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC性能。你先想想,如果没有分代,那我们所有的...

类加载器文件

  • 2015年10月02日 16:04
  • 17KB
  • 下载

深入理解Java类加载器(1):Java类加载原理解析

1       基本信息 每个java开发人员对java.lang.ClassNotFoundExcetpion这个异常肯定都不陌生,这背后就涉及到了java技术体系中的类加载。Java的类加载...

类加载器(java)

  • 2014年02月26日 18:01
  • 26KB
  • 下载

《Java虚拟机原理图解》5. JVM类加载器机制与类加载过程

一、Java语言的跨平台性的含义 Java语言之所以说它是跨平台的、可以在当前绝大部分的操作系统平台下运行,是因为Java语言的运行环境是在Java虚拟机中。 Java虚拟机消除了各个平台之间的差异...

java中类加载、类加载器详细解析

1、一个类编译完后会生成一个class文件。Class文件经历以下过程进行执行: 1、加载:加载class文件的信息加载到内存中。由硬盘到内存的迁移。   将其放在运行时数据区的方法区内,然后在堆区创...

java面试基础-Java类加载原理及类加载器

Java和其他语言不同的是,Java是运行于Java虚拟机(JVM)。这就意味着编译后的代码是以一种和平台无关的格式保存的,而不是某种特定的机器上运行的格式。这种格式和传统的可执行代码格式有很多重要的...

Java虚拟机-类加载器和类加载过程

类加载器java.lang.ClassLoader类及其子类可以让java代码动态地加载到JVM中。每一个类都有加载它的ClassLoader的引用。每一个类加载器类都有一个加载它的父类加载器,类加载...
  • waixin
  • waixin
  • 2016年01月30日 16:23
  • 379
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:采用类加载器加载多次类,perm区满了,发生FGC
举报原因:
原因补充:

(最多只允许输入30个字)