我有一个自定义类加载器,这样桌面应用程序就可以动态地从我需要访问的应用服务器中开始加载类。我们这样做是因为要加载的jar包数量太多了(如果我们想要发布它们的话)。如果不在运行时从AppServer库动态加载类,我们还会遇到版本问题。
现在,我遇到了一个问题,我需要与两个不同的AppServer通信,并发现根据我先加载谁的类可能会出现严重故障... 有没有办法在不实际杀死JVM的情况下强制卸载类?
希望这能说得清楚。
我有一个自定义类加载器,这样桌面应用程序就可以动态地从我需要访问的应用服务器中开始加载类。我们这样做是因为要加载的jar包数量太多了(如果我们想要发布它们的话)。如果不在运行时从AppServer库动态加载类,我们还会遇到版本问题。
现在,我遇到了一个问题,我需要与两个不同的AppServer通信,并发现根据我先加载谁的类可能会出现严重故障... 有没有办法在不实际杀死JVM的情况下强制卸载类?
希望这能说得清楚。
我在一个项目中使用了MultiClassloader的思想,其中包含用户定义脚本的类必须从内存中加载和卸载,并且它运行得非常好。
是的,有方法可以加载类并稍后“卸载”它们。关键是实现自己的类加载器,该加载器位于高级类加载器(系统类加载器)和应用服务器的类加载器之间,并希望应用服务器的类加载器将类加载委托给上层加载器。
一个类由其包,名称和最初加载它的类加载器定义。编写一个“代理”类加载器,它是启动JVM时加载的第一个类加载器。工作流程:
java.x
和sun.x
委派给系统类加载器(这些必须不通过任何其他类加载器加载,而只能通过系统类加载器加载)。如果正确执行,就不应出现ClassCastException或LinkageError等问题。
如需了解类加载器层次结构的更多信息(是的,这正是您在此实现的内容;-),请参阅Ted Neward的《服务器端Java编程》——这本书帮助我实现了与您想要的非常相似的东西。
ClassLoader
有点太多了,每个JAR文件一个ClassLoader
是有道理的。可以更具体地说明如何在提议的方案中强制上传类吗?例如,我怎样才能保证被ClassLoaderA加载的类的实例不被ClassLoaderB加载的实例所引用? - dma_k我编写了一个自定义的类加载器,可以在不使用GC类加载器的情况下卸载单个类。 Jar Class Loader
JarClassLoader
,你可以在其上调用getLoadedClasses()
,然后迭代每个类并卸载它。 - Ercksen类加载器可能是一个棘手的问题。如果您使用多个类加载器并且没有明确定义它们之间的交互,那么您可能会遇到问题。我认为,为了真正能够卸载一个类,您需要删除所有对任何类(及其实例)的引用,这样才能实现。
大多数需要执行此类操作的人最终使用 OSGi。OSGi非常强大,而且惊人地轻量级且易于使用。
你可以卸载一个ClassLoader,但你不能卸载特定的类。更具体地说,你不能卸载在不受你控制的ClassLoader中创建的类。
如果可能的话,建议使用自己的ClassLoader以便卸载。
类与其ClassLoader实例之间存在隐式强引用,反之亦然。它们像Java对象一样进行垃圾回收。如果不使用工具接口或类似方法,则无法删除单个类。
仍然可能出现内存泄漏。对您的类或类加载器的任何强引用都将导致整个内容泄漏。例如,在Sun的ThreadLocal、java.sql.DriverManager和java.beans实现中就会发生这种情况。
java.lang.System.gc()
。它会显式地触发垃圾回收器。