【问题标题】:JNA Library Reload Under Win32 HangsWin32 下 JNA 库重新加载挂起
【发布时间】:2011-10-17 14:52:29
【问题描述】:

我在这里遇到了一个有趣的 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'

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

【问题讨论】:

    标签: java 32bit-64bit jna


    【解决方案1】:

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

    【讨论】:

    • JNA 是为允许这种重新加载而编写的,因此如果您有可重现的测试用例,请在 JNA 项目站点github.com/twall/jna/issues 上提交问题。可能是 JNA 错误,也可能是挂在原始共享库上的系统。
    • 顺便说一句,如果您的“测试”使用的是 C 库,那么您肯定无法重新加载它,因为它已经被 VM 本身使用了。
    • 您的测试还应该使用 Wea​​kReference 或类似方法来检测对象何时实际被 GC'd。当 NativeLibrary 对象完成时,本机库句柄在 NativeLibrary.dispose() 中关闭。
    • Welp,应该总是写一个测试用例,现在我正在写一个裸测试用例似乎工作正常,我敢打赌我需要在我的生产代码中使用 Wea​​kReference(我打赌它实际上并没有处理图书馆出于某种原因),感谢该课程的提示,非常有用!当我重新实现它时,我会密切关注这个问题。
    猜你喜欢
    • 2011-09-02
    • 1970-01-01
    • 1970-01-01
    • 2010-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-24
    相关资源
    最近更新 更多