我正在使用JNA将回调函数从Java传递到本机代码。我可以很好地调用java inteface方法,问题是在调用该函数约40次后,我得到了SIGSEV,程序终止了。
当本地代码调用该方法时,SIGSEV发生在该行。
这与Java函数句柄上的一些垃圾回收相关吗?有办法防止这种情况吗?
注意:最接近的线程是“从本地pthread调用Java方法时的SIGSEV”。尽管他使事情变得全球化,但他似乎在本土方面解决了他的问题。
我尝试使java方法同步,但这没有帮助。我还修改了本机调用以启动pthread,然后调用java方法。这样做时,该方法可能调用了1000次,然后得到了SIGSEV
我在Java方面
public interface handler extends Callback {
void invoke();
}
static class test_start implements handler {
public synchronized void invoke() {
System.out.println("Hello");
}
}
答案 0 :(得分:1)
您是对的,您怀疑GC是您的问题,也是documented in JNA。
摘要:您需要在Java端对您的Callback Handler保持强大的引用,以防止垃圾回收。
实现高度依赖于您的体系结构。如果处理程序是全局处理程序,则可以将其保存在静态字段中(GC通常仅在卸载类时才收集静态字段数据)。如果您的处理程序绑定到具体的Java类,则可以使用静态WeakHashMap保留引用,直到收集Java对象为止(假设这也表明本机端将不再调用该处理程序)。如果处理程序与固定的生命周期相关联,我将实现一个AutoCloseable帮助器对象,该对象在关闭时注销您的处理程序。
应注意,在所有实现中,您必须确保对处理程序进行引用。对于在注销处理程序之后从close方法运行Reference#reachabilityFence的AutoClosable实现,这是明智的决定。