JNI не может освободить память

#java #android #android-ndk #jvm #java-native-interface

#java #Android #android-ndk #jvm #java-native-interface

Вопрос:

Это код JNI на C :

 extern "C" JNIEXPORT jbyteArray JNICALL
Java_cn_rilled_encoder_JNIEncoder_encodeEncryptBuff(
        JNIEnv* env,
        jobject obj,
        jbyteArray ucInBuffer,
        jintArray unInbufferLen,
        jintArray unOutbufferLen) {

    jbyte *bytes;
    bytes = env->GetByteArrayElements(ucInBuffer, 0);
    int chars_len = env->GetArrayLength(ucInBuffer);
    // chars = new unsigned char[chars_len];
    unsigned char* chars = (unsigned char *) malloc(chars_len);
    memset(chars,0,chars_len);
    memcpy(chars, bytes, chars_len);
    env->ReleaseByteArrayElements(ucInBuffer, bytes, 0);

    int inLength = env->GetArrayLength(unInbufferLen);
    int* inArray = env->GetIntArrayElements(unInbufferLen,0);

    int outLength = env->GetArrayLength(unOutbufferLen);
    int* outArray = env->GetIntArrayElements(unOutbufferLen,0);

    unsigned char* encryptBuff = WCCEncode_Encrypt_Buff(chars, (unsigned int*)inArray, (unsigned int*)outArray);

    jbyteArray bArray=env->NewByteArray(*outArray);

    env->SetByteArrayRegion(bArray, 0, *outArray, (jbyte *)encryptBuff);
    //env->DeleteLocalRef(bArray);
    //env->ReleaseByteArrayElements(bArray, (jbyte *)encryptBuff, 0);
    env->ReleaseIntArrayElements(unInbufferLen, inArray, NULL);
    env->ReleaseIntArrayElements(unOutbufferLen, outArray, NULL);
    free(chars);

    return bArray;
}
  

Это Java-код JNI:

 public class JNIEncoder {

    static {
        System.loadLibrary("native-lib");
    }

    public static native byte[] encodeEncryptBuff(byte[] ucInBuffer, int[] unInbufferLen, int[] unOutbufferLen);

}

  

Вызовите это в потоке Java:

 byte[] result = JNIEncoder.encodeEncryptBuff(content, new int[]{content.length}, outLength);
  

использование памяти:

использование памяти

использование памяти после освобождения символов:

введите описание изображения здесь

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

1. Основываясь на том, что вы нам показали, вы никогда не освобождаете chars . Почему вы даже используете new unsigned char[] вместо чего-то вроде std::vector<unsigned char> , который будет автоматически выпущен, когда он выйдет за рамки? GetByteArrayElements возможно, вы даже уже создали копию для вас, но вы никогда не проверяете это. И я не понимаю, почему параметры длины вашей encodeEncryptBuff функции сами по себе являются массивами (?).

2. Я думаю, вам придется написать отдельную функцию в вашем JNI, чтобы освободить память после вашей операции, в отличие от Java, C не будет освобождать память.

3. @Michael Извините, я впервые использую JNI, и мой код выглядит не очень хорошо. Я изменил код, использование памяти намного лучше, чем раньше, но это все еще кажется проблемой. Большое вам спасибо за ваш ответ.

Ответ №1:

Я решил проблему с delete encryptBuff .

Новый код

 ...
unsigned char* chars = (unsigned char *) malloc(chars_len);
...
free(chars);
delete encryptBuff;

return bArray;
  

Новое использование памяти:

новое использование памяти