我正在寻找一些关于在多个JNI调用之间缓存和重用Bridj JNI对象的指导原则。我发现缓存JNI对象极大地加快了通过JNI调用C函数的速度,但它也会导致一些数值稳定性问题。基本上,有时相同的C函数使用相同的参数会产生不同的结果。
我发现这个页面讨论了如何缓存JNI对象。http://www.latkin.org/blog/2016/02/01/jni-object-lifetimes-quick-reference/
有没有人用BridJ这样做,有没有关于如何缓存原语、结构、指针等的提示?
发布于 2017-08-22 21:40:19
一般来说,只需要知道java对所有Bridj指针的引用应该被保留,这样它们就不会被JVM垃圾收集器收集。一旦发生这种情况,Bridj/JNI将释放为这些指针分配的内存。
需要注意的一种特殊情况是:假设您创建了一个自动生成(使用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"))仅保留对结构对象的引用是不够的,还需要单独维护对pointerToCString("a")的引用。如果没有,一旦这个指针被垃圾收集器回收,Bridj/JNI将释放分配的内存。这在上面的代码中并不明显,因为它建议SomeStruct()对象无论如何都应该保留对pointerToCString("a")指针的引用。
https://stackoverflow.com/questions/45770502
复制相似问题