如何在 Java 中卸载已加载的类?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2095974/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to unload an already loaded class in Java?
提问by GuruKulki
How to unload a class from the class loader, so that I can use the recently changed class on the fly without restarting my application (hot deployment)? Is it possible to do that?
如何从类加载器卸载类,以便我可以在不重新启动应用程序(热部署)的情况下即时使用最近更改的类?有可能这样做吗?
回答by b_erb
You can't unload a class that is actually in use. But you might want to have a look at platforms like OSGi, if you want to reload or redeploy your application during runtime.
您无法卸载实际正在使用的类。但是,如果您想在运行时重新加载或重新部署您的应用程序,您可能想看看 OSGi 之类的平台。
回答by Jim Barrows
Java rebel reloads changed classes on the fly. See the jrebel website for details. I don't know that I would recommend this for a production environment though, because of performance issues. JRebel on occasion bogs things down momentarily when you've recompiled for a server.
Java rebel 会即时重新加载已更改的类。有关详细信息,请参阅jrebel 网站。由于性能问题,我不知道我会在生产环境中推荐这个。当您为服务器重新编译时,JRebel 有时会暂时陷入困境。
回答by Neil Coffey
You can't explicitly unloada class.
您不能显式卸载类。
In principle, you can expicitly reloada class via Classloader.loadClass(). From that moment onwards, all new instances of that class will use the new definition.
原则上,您可以通过Classloader.loadClass ()显式地重新加载一个类。从那一刻起,该类的所有新实例都将使用新定义。
In any case, I would proceed with extreme caution...
无论如何,我会非常谨慎地进行...
回答by Pindatjuh
You would have to create a custom ClassLoader
: which returns all Object
s wrapped inside a Proxy. The ClassLoader
must have a list of all referenced Proxies (keep this list WeakReference
d). If you decide to "unload" and thus "reload" any class, you wait untill the class is loaded, find all Proxy's in your list, and replace the actual object.
您必须创建一个 custom ClassLoader
: 它返回Object
包装在代理中的所有s。在ClassLoader
必须拥有所有引用的代理列表(保持这个名单WeakReference
d)。如果您决定“卸载”并因此“重新加载”任何类,请等到类加载完毕,在列表中找到所有代理,然后替换实际对象。
There are several problems: you need Reflection, to get all private variables and reset the internal state (see setAccesible
on Field
). Also multi-threading problems might occour, thus the Proxy must be synchronized: which makes it performing poor.
有几个问题:您需要反射,以获取所有私有变量并重置内部状态(参见setAccesible
参考资料Field
)。也可能会出现多线程问题,因此必须同步代理:这使其性能不佳。
You can better look for Google's Guice dependency solution, which enables unplugging and reloading modules at runtime. This might be a solution, but way too bloated for a small app. Still: I'm not sure wheter the GC also unloads unused classes.
你可以更好地寻找谷歌的 Guice 依赖解决方案,它可以在运行时拔出和重新加载模块。这可能是一个解决方案,但对于一个小应用程序来说太臃肿了。仍然:我不确定 GC 是否也会卸载未使用的类。