首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >卸载类加载程序

卸载类加载程序
EN

Stack Overflow用户
提问于 2013-04-30 19:03:50
回答 2查看 7.6K关注 0票数 7

我的最终目标是能够在类已经加载到JVM之后重新加载它们。

在阅读了下面的答案用java卸载类?之后,我一直在尝试实现我自己的class,它本身为它加载的每个类创建了一个不同的类加载器实例(相同类型的类本身)。

因此,结果是每一个类-装载机一个类。

其目的是能够GC类,即它的所有实例,然后卸载它的类加载器,并能够从它的字节中重新加载同一个类。

问题是--我可以看到我的类实例正在使用finalize()方法进行垃圾收集,但是我不能让类加载器卸载,或者被垃圾收集。

是否有任何代码示例,一个简单的测试,显示如何完成?

谢谢,任何帮助都将不胜感激。

编辑

更清楚的是,我对代码示例很感兴趣,在这些示例中,新对象的实例化是通过' new ( )‘操作数进行的,类加载器没有显式地重新加载类,而是在调用下一个'new( )’之后。

EN

回答 2

Stack Overflow用户

发布于 2013-04-30 19:42:28

如果没有对类加载器的引用,则应该对其进行垃圾收集。我从@PeterLawrey (谢谢)获得了这段代码 (它做的事情与您的相同),在自定义的类加载器finalize()方法中放入一个日志,并且瞧,类加载器是在它们加载的类为gc之后被垃圾收集的:

代码语言:javascript
复制
 /* Copyright (c) 2011.  Peter Lawrey
 *
 * "THE BEER-WARE LICENSE" (Revision 128)
 * As long as you retain this notice you can do whatever you want with this stuff.
 * If we meet some day, and you think this stuff is worth it, you can buy me a beer in return
 * There is no warranty.
 */


import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLClassLoader;

public class LoadAndUnloadMain {
    public static void main(String... args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InterruptedException {
        URL url = LoadAndUnloadMain.class.getProtectionDomain().getCodeSource().getLocation();
        final String className = LoadAndUnloadMain.class.getPackage().getName() + ".UtilityClass";
        {
            ClassLoader cl;
            Class clazz;

            for (int i = 0; i < 2; i++) {
                cl = new CustomClassLoader(url);
                clazz = cl.loadClass(className);
                loadClass(clazz);

                cl = new CustomClassLoader(url);
                clazz = cl.loadClass(className);
                loadClass(clazz);
                triggerGC();
            }
        }
        triggerGC();
    }

    private static void triggerGC() throws InterruptedException {
        System.out.println("\n-- Starting GC");
        System.gc();
        Thread.sleep(100);
        System.out.println("-- End of GC\n");
    }

    private static void loadClass(Class clazz) throws NoSuchFieldException, IllegalAccessException {
        final Field id = clazz.getDeclaredField("ID");
        id.setAccessible(true);
        id.get(null);
    }

    private static class CustomClassLoader extends URLClassLoader {
        public CustomClassLoader(URL url) {
            super(new URL[]{url}, null);
        }

        @Override
        protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
            try {
                return super.loadClass(name, resolve);
            } catch (ClassNotFoundException e) {
                return Class.forName(name, resolve, LoadAndUnloadMain.class.getClassLoader());
            }
        }

        @Override
        protected void finalize() throws Throwable {
            super.finalize();
            System.out.println(this.toString() + " - CL Finalized.");
        }
    }
}

class UtilityClass {
    static final String ID = Integer.toHexString(System.identityHashCode(UtilityClass.class));
    private static final Object FINAL = new Object() {
        @Override
        protected void finalize() throws Throwable {
            super.finalize();
            System.out.println(ID + " Finalized.");
        }
    };

    static {
        System.out.println(ID + " Initialising");
    }
}
票数 10
EN

Stack Overflow用户

发布于 2013-08-07 12:09:47

、IBM、VM、中,情况不同,因为类加载器的卸载只在全局gc期间发生。这可能会导致全局gc中的大量停顿时间,并在创建大量类加载器时导致内存不足。我在JMXMP中遇到了这个问题,其中为MBeanServerRequestMessage.CREATE_MBEAN_LOADER_PARAMS类型的每个远程消息创建了一个MBeanServerRequestMessage.CREATE_MBEAN_LOADER_PARAMS类加载器实例。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16307149

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档