如何在Java中卸载已加载的类?

时间:2010-01-19 18:28:19

标签: java classloader

如何从类加载器中卸载一个类,以便我可以动态使用最近更改的类而无需重新启动我的应用程序(热部署)?有可能吗?

4 个答案:

答案 0 :(得分:6)

Java反叛者即时重新加载更改的类。见the jrebel website for details。由于性能问题,我不知道我会为生产环境推荐这个。当你为服务器重新编译时,JRebel偶尔会陷入困境。

答案 1 :(得分:4)

您无法卸载实际使用的类。但是,如果要在运行时重新加载或重新部署应用程序,可能需要查看OSGi等平台。

答案 2 :(得分:4)

您无法明确卸载类。

原则上,您可以通过Classloader.loadClass()显式地重新加载一个类。从那一刻开始,该类的所有新实例都将使用新定义。

无论如何,我会极其小心......

答案 3 :(得分:2)

您必须创建一个自定义ClassLoader:它将返回包含在代理中的所有ObjectClassLoader必须包含所有引用代理的列表(保留此列表WeakReference d)。如果您决定“卸载”并因此“重新加载”任何类,则等待直到加载该类,找到列表中的所有代理,并替换实际对象。

有几个问题:您需要Reflection,获取所有私有变量并重置内部状态(请参阅setAccesible上的Field)。此外,多线程问题可能会出现,因此必须同步Proxy:这使得它表现不佳。

您可以更好地查找Google的Guice依赖项解决方案,该解决方案可以在运行时拔出和重新加载模块。这可能是一个解决方案,但对于小型应用来说太过臃肿了。仍然:我不确定GC是否也会卸载未使用的类。