在 JNI 实现中创建静态全局变量是否不好?

Clo*_*ees 4 c java performance java-native-interface static

我是 JNI 新手,所以这个天真的问题的答案可能是肯定的。

目前的问题是我正在实现 JNI 绑定到某些 C 库来完成繁重的工作。

在进行实际计算之前,C 库需要首先从共享内存加载辅助数据结构(并返回指向“大”结构的指针),或者如果该结构在共享内存中不可用,则通过提供的路径从磁盘加载记忆。

辅助结构将用作const.

为了避免每次都从磁盘加载,我正在考虑的是创建一个static int表示大结构已正确初始化的信号:

static int big_struct_loaded_in_mem = 0;

void Java_className_dowork(/*parameters*/){
    if(!big_struct_loaded_in_mem){
        // load struct
        big_struct_loaded_in_mem = 1;
    }
    // load from shared mem then do work using big_struct
    load_from_shm();
}

void Java_className_cleanup(/*parameters*/){
    //free up mem
    big_struct_loaded_in_mem = 0;
}
Run Code Online (Sandbox Code Playgroud)

为了简单起见,假设 Java 调用方和本机函数是单线程的。

非常感谢!

注意:当然,没有 的简单修复static int可能只是load_from_shm()每次调用并测试返回的指针,但我很好奇这个特定的想法是否不好:即在 JNI 绑定中创建静态全局变量。

Pau*_*mer 6

是的,您应该避免 JNI 中的全局静态。

Java 可以加载一个类的多个实例(因为例如有多个类加载器),并且静态将在所有这些实例之间共享。不幸的是,清理调用也会如此,如果类的一个实例被销毁而另一个实例仍在使用中,则会导致不一致。

使用本机类构造函数/终结器并在此时分配/释放内存资源会更明智。这还允许使用不同的用例,例如根据加载类的 ClassLoader 进行不同的配置 - 例如在 EJB 应用程序容器中。

为了简单起见,假设 Java 调用方和本机函数是单线程的。

错误的假设。JVM 在幕后做很多事情。