在不重新启动jvm的情况下卸载和重新加载dll



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

请帮帮我们。

提前谢谢。

Krgds,Debojit

您可以卸载它。但是这样做可能不安全。

假设您在Windows平台上运行,而不知道DLL的详细信息,则不可能安全地卸载库。根据FreeLibrary函数的文档:

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

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

此外,卸载库可能无法解决您的问题。结束整个进程可以解决问题,因为这会导致进程使用的所有内容都被释放/关闭(在大多数情况下,总是有例外…)。简单地卸载一个加载到地址空间的库并不能做到这一点。卸载库可能会做你想做的事情——如果库是这样设计的。考虑到它在正常使用时显然无法正常工作,我想说,如果在使用时卸载库不会造成更严重的问题,那么它在异常使用时正常工作的几率就不是很大了。

你需要真正解决问题,而不是简单地尝试一下,看看它们是否有效。

最新更新