卸载并重新加载DLL而不重新启动jvm

时间:2015-12-16 06:52:03

标签: dll java-native-interface reload

我正在使用一个java程序,我需要调用一个本地库,以便调用其他的dll,然后联系一些Remote" Amadeus" (航空相关服务)服务。 问题陈述: 每次联系远程服务时,jni dll都会创建一个会话,并在完成预期任务后关闭会话。它与jdbc方法非常相似,不涉及连接池。 现在似乎会话实际上没有正确关闭,并且在服务器端它最终导致最大会话异常并拒绝任何进一步的连接请求。 似乎在dll-remote服务连接端存在一些问题,因为从java代码通过调用本机调用正确地关闭了连接。 确定的解决方法: 重新启动应用程序可以解决此问题,因为它会强制关闭所有打开的连接。 我们暂时无权更改dll,因此我们正在考虑是否可以在不重新启动jvm但重新连接(卸载和重新加载)dll的情况下重新启动jvm。 这里我们认为如果我们可以断开dll,分配给dll的所有内存都将被清除,因此将强制关闭/收集服务器端的开放会话。 题: 我们真的可以卸载然后重新加载dll而无需重新启动jvm吗?

请帮助我们。

提前致谢。

Krgds, Debojit

1 个答案:

答案 0 :(得分:0)

你可以卸载它。但是,这样做可能并不安全。

假设您在不知道DLL详细信息的情况下在Windows平台上运行,则无法安全地卸载该库。根据{{​​3}}的文档:

  

使用返回的句柄调用FreeLibrary时要小心   的GetModuleHandle。 GetModuleHandle函数不会递增a   模块的引用计数,所以将此句柄传递给FreeLibrary即可   导致模块过早卸载。

由于您无法直接访问用于加载库的句柄,也无法直接访问库中的所有引用,因此您无法知道是否不再使用对库的所有引用。 / p>

此外,卸载库可能无法解决您的问题。结束整个过程可以解决问题,因为这会导致过程使用的所有内容被释放/关闭(在大多数情况下 - 总是存在异常......)。只需卸载加载到地址空间的一个库就不会这样做。卸载库可能会做你想要的 - 如果库设计为以这种方式工作。鉴于它在正常使用时显然不能正常工作,我说它在异常使用时工作正常的几率并不是很好 - 如果在使用库时将它卸下来不会导致更严重的问题。

你需要真正解决问题 - 不要简单地尝试并看看它们是否有效。