我正在寻找一些关于在多个JNI调用之间缓存和重用Bridj JNI对象的指南。我发现缓存JNI对象大大加快了对JNI调用C函数的速度,但它也导致了一些数值稳定性问题。基本上,有时相同参数的相同C函数会产生不同的结果。
我发现这个页面讨论了如何缓存JNI对象。 http://www.latkin.org/blog/2016/02/01/jni-object-lifetimes-quick-reference/
有没有人在BridJ中做过任何有关如何缓存基元,结构,指针等的提示?
答案 0 :(得分:0)
通常,只要知道应该保留对所有Bridj指针的java引用就足够了,这样它们就不会被JVM垃圾收集器收集。一旦发生,Bridj / JNI将释放为这些指针分配的内存。
需要注意的一个特殊情况是: 想象一下,您创建了一个自动生成的Java实例(使用JNAerator)类:
@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"))
仅保留对struct对象的引用是不够的,还应单独维护对pointerToCString(“a”)的引用。如果没有,一旦垃圾回收器收集了该指针,Bridj / JNI将释放已分配的内存。从上面的代码中不明显,因为它表明SomeStruct()对象应该保持对pointerToCString(“a”)指针的引用。