Java Win32挂起下的JNA库重新加载

Java Win32挂起下的JNA库重新加载,java,32bit-64bit,jna,Java,32bit 64bit,Jna,我这里有一个有趣的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, LibHandle

我这里有一个有趣的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应用程序,这没什么大不了的),但我仍然想知道这是否是一个bug

编辑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) + "'");
        
        
    }
}

工作正常,天哪,我假设可能有其他东西在我的生产代码中引用了它,但它实际上并没有发布它,请始终检查弱引用

这似乎是一个bug,除了重新启动服务之外,我还没有找到其他解决方案。无论如何,可能最好在库更新时重新启动。

JNA是为了允许这种重新加载而编写的,因此如果您有一个可复制的测试用例,请在JNA项目站点的上提交一个问题。这可能是一个JNA错误,或者可能是挂在原始共享库上的系统。顺便说一句,如果您的“测试”使用的是C库,您肯定无法重新加载它,因为它已经被VM本身使用。您的测试还应该使用WeakReference或类似工具来检测对象何时实际被GC删除。当NativeLibrary对象完成时,NativeLibrary.dispose()中的本机库句柄关闭。Welp应该总是编写一个测试用例,现在似乎工作正常,因为我正在编写一个简单的测试用例,我打赌我需要在我的生产代码中使用WeakReference(我打赌出于某种原因,它实际上并没有处理库),谢谢你在那门课上的提示,非常有用!当我重新实现它时,我会关注这个问题。
Path: G:\Source\jnaFailure
Expecting 'Test', result: 'Test'
Collected
Expecting 'Test', result: 'Test'