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

标签 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 中做过吗,有关于如何缓存基元、结构、指针等的提示吗?

最佳答案

通常知道应该保留对所有 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/

相关文章:

java - 如何使用 Java 解析后台进程的输出?

java - 使用 solrj 和 java 以编程方式将数据加载到 solr

c - 如何在 32 位时间库中使用 mktime64()、time64() 和 localtime64() 函数?

scala - 在 Akka 中捕获异常作为参与者的响应

scala - 处理集合时如何改变类型参数?

scala - Spark 斯卡拉 : JniBasedUnixGroupsMapping: Error getting groups for XXX: The user name could not be found

java - 拆分字符串但仍显示所有元素

java - 如何从字符串对象中获取数字?

c++ - 预期的声明说明符或 '...' 之前的 'boolean'

arrays - 如何使用 scanf 将元素接收到数组中?