如何正确地从JNI释放内存?

时间:2020-09-26 21:30:30

标签: java c++ memory 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, &isCopy);
    jdouble* po = env->GetDoubleArrayElements(originalMatrix, &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 :(得分:0)

似乎正确。对于输入数组,您可以在0调用中将JNI_ABORT替换为ReleaseDoubleArrayElements,以确保在GetDoubleArrayElements给您副本的情况下不会进行回写。

对于输出数组,您还可以考虑使用输入数组的isCopy结果来确定是否使用SetDoubleArrayRegion而不是GetDoubleArrayElements / ReleaseDoubleArrayElements

相关问题