有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

c如何在Java/Scala中正确缓存BridJNI对象

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

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

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


共 (1) 个答案

  1. # 1 楼答案

    一般来说,只需知道所有Bridj指针的java引用都应该保留,这样JVM垃圾收集器就不会收集它们。一旦发生这种情况,Bridj/JNI将释放分配给这些指针的内存

    需要注意的一个特殊情况是: 想象一下,您创建了一个自动生成(使用JNAvior)类的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”)指针的引用