在java中可靠地卸载dll
我正在尝试在java中卸载dll。我已阅读此和this 但似乎你不能保证dll实际上会在某个时间被卸载。这是因为 System.gc() 只是“友好地请求”垃圾收集器运行。
所以这里是对情况的细分。我有一个 dll,它通过 JNI 提供一些功能。我们将此 dll 称为 MainDll。 MainDll 是通过调用 System.load("MainDll") 加载的。我需要能够动态卸载和加载这个 dll。
是否可以创建另一个 dll,其唯一目的是加载和卸载 MainDll。我们将这个 dll 称为 LoaderDll。然后我可以简单地调用 System.load("LoaderDll") 并使用一些本机函数来加载和卸载 MainDll。这样做的原因是我可以访问本机系统上的函数,这些函数可以动态加载和卸载 dll。棘手的部分是,如果从 LoaderDll 内部加载,我是否仍然能够访问我在 MainDll 中编写的本机函数。
抱歉,如果这是一个令人困惑的问题。似乎有点难以解释。
谢谢
I am trying to unload a dll in java. I have read this and this but it seems that you can not guarantee that the dll will actually be unloaded at a certain time. This is because System.gc() simply "asks kindly" for the garbage collector to run.
So here is a break down of the situation. I have a dll that provides some functionality via JNI. Lets call this dll MainDll. MainDll is loaded from a call to System.load("MainDll"). I need to be able to unload and load this dll on the fly.
Is it possible to create another dll that's sole purpose is to load and unload MainDll. Lets call this dll LoaderDll. I could then simple call System.load("LoaderDll") and have some native functions to load and unload MainDll. The reason for doing this, is I have access to functions on the native system that can load and unload the dll on the fly. The tricky part with this is, will I have still be able to access the native functions I have written in MainDll if it loaded from inside LoaderDll.
Sorry if this is a confusing question. It seems its a little difficult to explain.
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
创建一个执行加载/卸载的包装 DLL。 DLL 中还具有包装方法,这些方法将调用委托给加载的 MainDll DLL。这样你的 Java JNI 代码只知道一个 DLL。它仍然可以请求卸载 [LoaderDll::unload()],从而在内部卸载 MainDll。
只要 LoaderDll 中的方法/函数在当前未加载 MainDll 时调用它们时可以触发 MainDll 的加载,就应该有效,假设这是所需的行为而不是引发异常/错误。
这样做的一个问题是 LoaderDll 总是会被加载。
Create a wrapper DLL that does the loading/unloading. Also have wrapper methods in the DLL that turn around and delegate the calls to the loaded MainDll DLL. This way your Java JNI code only knows about a single DLL. It can still request the unload [LoaderDll::unload()] which internally unloads the MainDll.
This should work as long as the methods/functions in LoaderDll can trigger a load of MainDll when they are called when MainDll is not currently loaded, assuming that is the desired behavior instead of throwing an exception/error.
One issue with this would be that LoaderDll would always be loaded.
添加间接级别。
让您的本机方法调用 LoaderDLL 中的转发例程。转发例程可以使用 C 工具将调用转发到 mainDLL 中的代码。
Add a level of indirection.
Make your native methods call forwarding routines in LoaderDLL. The forwarding routines can use C facilities to forward the calls to code in mainDLL.
如果您需要动态加载和卸载代码,您是否考虑过OSGi。这至少在 felix 中有效。
在Oracle/Sun的JDK中,System.gc()会触发full gc(除非已在命令行中关闭)。它可能只是对其他 JVM 的提示。
If you have a need to dynamically load and unload code, have you considered OSGi. This works in felix at least.
In Oracle/Sun's JDK, System.gc() will trigger a full gc (unless it has been turned off on the command line). It could be just a hint on other JVMs.
根据您澄清的评论,我认为最简单的方法是生成一个新的 JVM,其唯一职责是管理您的 DLL。可能会公开 RMI 接口来访问这些类(尽管简单的流可能就足够了)。
Based on your clarifying comments, I think the simplest approach would be to spawn a new JVM, whose sole responsibility is managing your DLL. Probably exposing an RMI interface to access those classes (although a simple stream may be sufficient).
我还没有遇到 System.gc() 不触发垃圾收集器的情况,尽管这只是一个提示。
本教程实际上帮助我完成了我的工作:卸载 Java JNI DLL
I haven't still encountered a situation where System.gc() not to trigger the garbage collector although it is just a hint.
This tutorial actually helped me to do my work: Unload Java JNI DLL