Java中卸载dll
根据 this 和 this,似乎只有当对ClassLoader对象的引用消失并且垃圾收集器运行时才会卸载dll。如果是这种情况,是否可以简单地在一个线程中加载dll,然后杀死该线程来达到相同的效果,而不必创建自定义的ClassLoader?像这样的事情:
new Thread(
new Runnable()
{
public void run()
{
System.load("dll");
}
}
).start(); //Will load the dll, then there will be no references to the thread
System.gc(); //Will unload the dll
我可能会在现实生活中做一些比这更复杂的事情,但只是为了表明这一点。
According to this and this, it seems that a dll is only unloaded when the reference to the ClassLoader object is gone and the garbage collector runs. If this is the case, can you simply load the dll in a thread, and then kill the thread to achieve the same effect without having to create a custom ClassLoader? Something like this:
new Thread(
new Runnable()
{
public void run()
{
System.load("dll");
}
}
).start(); //Will load the dll, then there will be no references to the thread
System.gc(); //Will unload the dll
I would probably do something more elaborate than this in a real life setting, but just to show the point.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不,那是行不通的。该 dll 通过本机接口绑定到内存中的类对象。只要该类保留在内存中,该 dll 就不会卸载。
这与可以重新加载类(作为开发的一部分)的 servlet 容器非常相似 - 每个 Web 上下文总是有一个单独的类加载器(请参阅 tomcat 的类加载器文档)。
把它想象成一个意大利面条球——每一个参考都是意大利面条,只有当整个球是自由的时,整个混乱才能消失。
删除对类加载器已加载的任何类的对象的所有引用,最后删除对类加载器本身的引用。
只有这样,gc 才会摆脱它(并且
System.gc()
不保证它运行,它可能会在将来的某个时候运行)这可能很难实现 - 很多时候你会结束内存泄漏,因为有一些被遗忘的小意大利面让整个球保持活力。
No. That won't work. The dll is bound to the class object you have in memory with the native interface. As long as that class remains in memory, the dll won't unload.
This is very akin to servlet container that can reload classes (as part of development) - they always have a separate class loader per web context (look at tomcat's class loader documentation).
Think of it as a ball of spaghetti - every single reference is a spaghetti, and only if the whole ball is free, can the whole mess go away.
Drop all references to objects of any class that class loader has loaded, and finally the reference to the class loader itself.
Only then will the gc get rid of it (and
System.gc()
doesn't guarantee it runs, it may run sometime in the future)This can be really tricky to achieve - many times you end up with memory leaks since there's some tiny forgotten spaghetti keeping the whole ball alive.