Как правильно освободить память из JNI?

#java #c #memory #java-native-interface

#java #c #память #java-native-interface

Вопрос:

Из Java я вызываю матричное умножение (используется для вычисления мощности квадратной матрицы):

 // Java
public class Matrix {
    // ...
    native void power(double[] a, double[] b, int rows, int cols, int exponent);
    // ...
}
  

В C это реализовано следующим образом:

 JNIEXPORT void JNICALL power(JNIEnv* env, jobject o,
    jdoubleArray vals, jdoubleArray originalMatrix, jint aRows, jint aCols, jint i) {
            
    jboolean isCopy;

    // Get input array and result array to write values to.
    jdouble* pa = env->GetDoubleArrayElements(vals, amp;isCopy);
    jdouble* po = env->GetDoubleArrayElements(originalMatrix, amp;isCopy);

    // Keeping the result of the k-th multiplication.
    jdouble* tmp = new double[aRows * aCols];

    for (int k = 1; k < i; k  ) {
        multiply(po, pa, tmp, aRows, aCols, aCols);  // implemented elsewhere (but should be ok)
        memcpy(tmp, pa, aCols * aRows);
    }    
    
    env->ReleaseDoubleArrayElements(vals, pa, 0);    // <- THIS OK?
    env->ReleaseDoubleArrayElements(originalMatrix, po, 0);

    delete[] tmp;
}
  

Ответ №1:

Кажется, это правильно. Для входного массива, который вы могли 0 бы заменить JNI_ABORT в ReleaseDoubleArrayElements вызове, чтобы гарантировать, что обратная запись не будет выполнена в случае GetDoubleArrayElements , если вы получили копию.

Для выходного массива вы также можете рассмотреть возможность использования результата входного массива isCopy , чтобы определить, следует ли использовать SetDoubleArrayRegion вместо GetDoubleArrayElements / ReleaseDoubleArrayElements .

Комментарии:

1. Что на самом деле означает JNI_ABORT ‘

2. Это описано в документации JNI .

3. который я прочитал (извините, я должен был спросить лучше): «Что это значит JNI_ABORT: free the buffer without copying back the possible changes , какой буфер? И, если я хочу, чтобы значения вычислялись на C , тогда, я думаю, я хочу снова использовать их в Java, так JNI_ABORT что это не будет неправильным вариантом для меня?

4. «Какой буфер?» Тот, который вы получили от GetDoubleArrayElements . «если я хочу, чтобы значения вычислялись на C , тогда, я думаю, я хочу снова использовать их в Java» У меня создалось впечатление, что один из двух массивов использовался только в качестве входных данных. Для такого массива было бы уместно использовать JNI_ABORT .