【问题标题】:Reliabily unload dll in java在java中可靠地卸载dll
【发布时间】:2010-11-30 15:22:31
【问题描述】:

我正在尝试在 java 中卸载 dll。我已经阅读了thisthis,但您似乎无法保证 dll 会在某个时间实际被卸载。这是因为 System.gc() 只是“友好地请求”垃圾收集器运行。

所以这里是一个细分的情况。我有一个通过 JNI 提供一些功能的 dll。让我们将此 dll 称为 MainDll。 MainDll 是从对 System.load("MainDll") 的调用中加载的。我需要能够即时卸载和加载这个 dll。

是否可以创建另一个仅用于加载和卸载 MainDll 的 dll。让我们将此 dll 称为 LoaderDll。然后我可以简单地调用 System.load("LoaderDll") 并使用一些本机函数来加载和卸载 MainDll。这样做的原因是我可以访问本机系统上的函数,这些函数可以动态加载和卸载 dll。棘手的部分是,如果它是从 LoaderDll 内部加载的,我是否仍然能够访问我在 MainDll 中编写的本机函数。

对不起,如果这是一个令人困惑的问题。好像有点难以解释。

谢谢

【问题讨论】:

  • 你想用这种方式解决什么问题?(有没有确定性加载和卸载的替代方案,只是想得到一个更好的主意)
  • 为什么您需要能够动态加载/卸载 MainDLL?通常,加载/卸载问题出现在开发场景中,当 DLL 作为构建的一部分进行部署时。这是你的情况,还是有其他原因?
  • 它是一个视频会议应用程序。我想卸载它有几个原因。通话结束后,有很多不同的事情需要清理。可能会出问题。例如,如果 H.323 堆栈中存在问题。如果驱动程序已可靠损坏或应用程序无法按预期运行,我需要确保可以卸载然后重新加载驱动程序。

标签: java dll java-native-interface


【解决方案1】:

创建一个执行加载/卸载的包装 DLL。在 DLL 中也有包装器方法,可以将调用委托给加载的 MainDll DLL。这样,您的 Java JNI 代码只知道单个 DLL。它仍然可以请求在内部卸载 MainDll 的卸载 [LoaderDll::unload()]。

只要在当前未加载 MainDll 时调用 LoaderDll 中的方法/函数可以触发 MainDll 的加载,这应该可以工作,假设这是所需的行为而不是引发异常/错误。

这样做的一个问题是总是会加载 LoaderDll。

【讨论】:

    【解决方案2】:

    添加一个间接级别。

    让您的本地方法调用 LoaderDLL 中的转发例程。转发例程可以使用 C 工具将调用转发到 mainDLL 中的代码。

    【讨论】:

      【解决方案3】:

      如果您需要动态加载和卸载代码,您是否考虑过 OSGi。这至少在 felix 中有效。

      在 Oracle/Sun 的 JDK 中,System.gc() 将触发一次完整的 gc(除非它已在命令行中关闭)。这可能只是对其他 JVM 的提示。

      【讨论】:

      • System.gc(),即使在sun jdk上,也只是提示
      • @ChristopherDancy 无论如何,这就是“提示”的作用。
      【解决方案4】:

      根据您澄清的 cmets,我认为最简单的方法是生成一个新的 JVM,其唯一职责是管理您的 DLL。可能会公开一个 RMI 接口来访问这些类(尽管一个简单的流可能就足够了)。

      【讨论】:

        【解决方案5】:

        我还没有遇到过 System.gc() 不触发垃圾收集器的情况,尽管这只是一个提示。 本教程实际上帮助我完成了我的工作:Unload Java JNI DLL

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-04-06
          • 2012-10-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多