JNI 缓存 java 数组

JNI cache java array

我有一个 java 应用程序和一些本机 C++ 代码。 java 应用程序运行一些线程。每个线程都有一个双精度数组,它作为参数传递给本机代码。到目前为止一切正常。现在在我的本机代码中,我想在数组中写入值。目前我正在通过:

  JNIEXPORT void JNICALL Java_JNIPerformanceTest_alterArray___3I_3D
    (JNIEnv *env, jobject, jintArray intArray, jdoubleArray doubleArray){

         jint count = env->GetArrayLength(doubleArray);
         jdouble* S_native = env->GetDoubleArrayElements(doubleArray, NULL);

         for (int i=0; i < count; i++) {
                S_native[i] = i;
         }

         jint count2 = env->GetArrayLength(intArray);
         jint* S_native2 = env->GetIntArrayElements(intArray, NULL);


         for (int i=0; i < count2; i++) {
                S_native2[i] = i;
         }

         env->ReleaseDoubleArrayElements(doubleArray, S_native, 0);
         env->ReleaseIntArrayElements(intArray, S_native2, 0);
    }

由于 GetArrayLength 和 GetDoubleArrayElements 需要一些时间,而且我总是将相同的 java 数组实例传递给本机代码,我想知道是否有没有获取元素指针并释放的解决方案函数调用。我已经尝试过全局存储指针,当然是

 env->NewWeakGlobalRef(array);

。但是,如果我不在此数组上调用 ReleaseDoubleArrayElements,则在 java 中检查时元素不会更改。 解决此类问题的最佳方法是什么?使用字节缓冲区?

这也是我的 java 代码:

    double ARRAY_SIZE = 10;

    for (int i = 0; i < 4; i++) {
        Thread thread = new Thread(new Runnable() {

            boolean done = false;

            @Override
            public void run() {
                while (true) {
                    double d[] = null;
                    int intArray[] = null;
                    if (!done) {
                        d = new double[ARRAY_SIZE];
                        for (int i = 0; i < ARRAY_SIZE; i++) {
                            d[i] = 222;
                        }

                        intArray = new int[ARRAY_SIZE];
                    }

                    long start = System.nanoTime();
                    alterArray(intArray, d);

                    long end = System.nanoTime();
                    System.out.println("test_alterArray: time for " + NUM_LOOPS + " loops: " + ((end - start) / 1000) + " us.");

                }
            }
        });
        thread.start();
    }

是的,正确的方法是使用 DirectByteBuffer。但是,它有其自身的缺点。例如,这样的 Buffer 没有数组支持,从 Java 端访问它可能效率较低。