我正在寻找一些关于在多个 JNI 调用之间缓存和重用 Bridj JNI 对象的指南。我发现缓存 JNI 对象极大地加快了通过 JNI 调用 C 函数的速度,但它也会导致一些数值稳定性问题。基本上,有时具有相同参数的相同 C 函数会产生不同的结果。
我发现这个页面讨论如何缓存 JNI 对象。 http://www.latkin.org/blog/2016/02/01/jni-object-lifetimes-quick-reference/
有人在 BridJ 中做过吗,有关于如何缓存基元、结构、指针等的提示吗?
最佳答案
通常知道应该保留对所有 Bridj 指针的 java 引用就足够了,这样它们就不会被 JVM 垃圾收集器收集。一旦发生,Bridj/JNI 将释放为这些指针分配的内存。
需要注意的一个特殊情况是: 假设您创建了一个自动生成(使用 JNAerator)类的 Java 实例:
@Library("libtarget.so")
public class SomeStruct extends StructObject {
public SomeStruct() {
super();
}
@Field(0)
public Pointer<Byte > p0() {
return this.io.getPointerField(this, 0);
}
@Field(0)
public SomeStruct p0(Pointer<Byte > p0) {
this.io.setPointerField(this, 0, p0);
return this;
}
...
}
然后
val struct = new SomeStruct()
struct.p0(pointerToCString("a"))
仅保留对结构对象的引用是不够的,还应单独维护对 pointerToCString("a") 的引用。否则,Bridj/JNI 将在垃圾收集器收集到该指针后释放分配的内存。从上面的代码来看并不明显,因为它表明 SomeStruct() 对象无论如何都应该保留对 pointerToCString("a") 指针的引用。
关于java - 如何在 Java/Scala 中正确缓存 Bridj JNI 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45770502/