我在这里遇到一个有趣的 JNA 问题。
在 JRE 1.6 和 1.7 x64 下,我可以像这样加载和卸载库:
this.Lib = (LibHandler)Native.loadLibrary(this.Name, LibHandler.class);
this.Lib.Initialize();
this.Lib = null;
Runtime.getRuntime().gc();
this.Lib = (LibHandler)Native.loadLibrary(this.Name, LibHandler.class);
this.Lib.Initialize();
这将加载它,运行初始化例程,将类设置为 null 并强制 GC 清理它,这将卸载库(我的误解,如果我做错了请纠正我!),和重新加载并重新初始化它。在 x64 上完美运行。
但是在 x86 上,这段代码将无法加载第二个 Initialize()(在这个例子中,它实际上只是返回 C 库),它会卡在那里什么都不做,我可以用这些库做其他一切,除了重新加载它们。
我是否遗漏了什么或者我是否偶然发现了一些需要报告给 JNA 开发团队的东西?
编辑:
我确实有办法处理这个问题(基本上是在库交换时重新启动 java 应用程序,这没什么大不了的),但我仍然想知道这是否是一个错误。
编辑 2:
写了一个测试用例以防我必须提交这个:
public class EntryPoint {
public static void main(String[] args) {
String path = new File("").getAbsolutePath();
System.out.println("Path: " + path);
ITest it = (ITest)Native.loadLibrary(path + "\\jnaFailureC_x86.dll", ITest.class);
System.out.println("Expecting 'Test', result: '" + it.myMethod().getString(0) + "'");
WeakReference<ITest> itRef = new WeakReference<ITest>(it);
it = null;
Runtime.getRuntime().gc();
if(itRef.get() != null){
System.out.println("Not collected.");
}else{
System.out.println("Collected");
}
it = (ITest)Native.loadLibrary(path + "\\jnaFailureC_x86.dll", ITest.class);
System.out.println("Expecting 'Test', result: '" + it.myMethod().getString(0) + "'");
}
}
Path: G:\Source\jnaFailure
Expecting 'Test', result: 'Test'
Collected
Expecting 'Test', result: 'Test'
工作正常,糟糕,我假设可能有其他东西在我的生产代码中引用了它,但实际上并没有发布它,请始终检查弱引用!
最佳答案
这似乎是一个错误,除了重启服务之外我还没有找到解决方案。无论如何,最好在库更新时重新启动。
关于java - JNA 库在 Win32 下重新加载挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6901714/