2

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

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

有没有人在 BridJ 中这样做,关于如何缓存原语、结构、指针等的任何提示?

4

1 回答 1

1

一般来说,知道应该保留对所有 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"))

仅保留对 struct 对象的引用是不够的,还应单独维护对 pointerToCString("a") 的引用。如果没有,Bridj/JNI 将在垃圾收集器收集此指针后释放分配的内存。上面的代码并不明显,因为它表明 SomeStruct() 对象无论如何都应该保留对 pointerToCString("a") 指针的引用。

于 2017-08-22T13:40:19.430 回答