如何在Java / Scala中正确缓存Bridj JNI对象

时间:2017-08-19 10:35:51

标签: java c scala java-native-interface bridj

我正在寻找一些关于在多个JNI调用之间缓存和重用Bridj JNI对象的指南。我发现缓存JNI对象大大加快了对JNI调用C函数的速度,但它也导致了一些数值稳定性问题。基本上,有时相同参数的相同C函数会产生不同的结果。

我发现这个页面讨论了如何缓存JNI对象。 http://www.latkin.org/blog/2016/02/01/jni-object-lifetimes-quick-reference/

有没有人在BridJ中做过任何有关如何缓存基元,结构,指针等的提示?

1 个答案:

答案 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”)指针的引用。