采用类加载器加载多次类,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



版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

类加载器文件

  • 2015-10-02 16:04
  • 17KB
  • 下载

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

Java的类加载机制是技术体系中比较核心的部分,虽然和大部分开发人员直接打交道不多,但是对其背后的机理有一定理解有助于排查程序中出现的类加载失败等技术问题,对理解java虚拟机的连接模型和java语言...

类加载器(java)

  • 2014-02-26 18:01
  • 26KB
  • 下载

线程上下文类加载器与服务器类加载原理

双亲委派机制以及类加载器的问题一般情况下.保证同一个类中所关联的其他类都是由当前类的类加载器所加载的。 比如,class A本身在Ext下找到.那么他里面new出来的一些类也就只能用Ext去查找了(...

使用类加载器加载配置文件

package com.franky.reflex; import java.io.InputStream; import java.util.Collection; import java.uti...

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

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

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

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

深入JVM系列(三)之类加载、类加载器、双亲委派机制与常见问题

一.概述 定义:虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型。类加载和连接的过程都是在运行期间完成的。 二. 类的加载...

自定义类加载器加载指定目录下的类

package com.itheima.classloader; import java.io.BufferedInputStream; import java.io.ByteArrayOutput...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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