JNI字节数组导致内存泄漏

4

我有一个调用本地函数多次的Java程序。我的问题是这个函数存在内存泄漏,而我尝试去解决它的所有方法都导致了内存转储。非常感谢您提供任何帮助。

这是我的代码:

JNIEXPORT void JNICALL Java_class_method_getInput
(JNIEnv *env, jobject obj)
{
    if (inputIsAvailable)
    {

    int size = getBufferCurrentIndex();
    size -= getBufferReadIndex();
    size *= 2;

    char *finalSendArray = new char[size];

    getCommand(finalSendArray);

    jbyteArray byteArray = env->NewByteArray(size / 2);
    env->SetByteArrayRegion(byteArray, 0, size / 2, (jbyte*) finalSendArray);

    while(methodID == 0)
    {
        jclass cls = env->GetObjectClass(obj);
        methodID = env->GetMethodID(cls, "setCommand", "([B)V" );
    }

    env->CallVoidMethod(obj, methodID, byteArray);

    //env->ReleaseByteArrayElements(byteArray, (jbyte*) finalSendArray, JNI_ABORT);

我的问题是,如果取消注释上面的代码,会导致内存转储,如果不取消注释,我的程序几分钟内就会耗尽内存。

    env->DeleteLocalRef(byteArray);
    delete[] finalSendArray;
    }
}

任何帮助都将不胜感激。谢谢!

先释放 byteArray,然后删除底层内存? - Kerrek SB
我的回答解决了你的问题吗?如果解决了,请将其标记为正确。你为什么要用C语言做这个?getCommand函数是做什么的?它能用Java实现吗?jni很昂贵。 - JustinDanielson
很抱歉听到这个。我并不是很确定;唯一能够提供的建议就是仔细阅读JNI规范,确保您理解所有不同的生命周期和依赖关系。 - Kerrek SB
你解决了这个问题吗?是什么原因导致的?我很好奇,因为我一直在处理一些与JNI相关的东西,经常遇到奇怪的问题。 - JustinDanielson
这不太好,我在这里也遇到了同样的问题。 - OnlyAngel
显示剩余3条评论
1个回答

4
ReleaseByteArrayElements函数也会释放内存,如果你使用JNI_ABORT参数。因此,当你稍后执行删除和释放操作时,其中一个指针指向未初始化的内存,这会导致崩溃。
这些方法中的一个将起作用,我相当确定是第一个方法起作用。
env->ReleaseByteArrayElements(byteArray, (jbyte*) finalSendArray, JNI_ABORT);
delete[] finalSendArray;

如果第一个失败,请尝试这个。

env->ReleaseByteArrayElements(byteArray, (jbyte*) finalSendArray, JNI_ABORT);
env->DeleteLocalRef(byteArray);

在ReleaseByteArrayElements之后添加一个打印语句,您会发现程序正在执行该命令并在Release/Delete[]上崩溃。 搜索"Table 4-10 Primitive Array Release Modes"

第一个引起 code *** glibc detected *** /usr/lib/jvm/java-7-openjdk-amd64/bin/java: double free or corruption (fasttop): 0x00007fb8a4001030 *** code,第二个我仍然有内存泄漏。我将确保内存泄漏确实存在。 - Tyler Davis
它可能在getCommand中。现在在同一位置不再崩溃了吗? - JustinDanielson
日志文件指向函数SetByteArrayRegion,它抛出了bad_alloc错误。 - Tyler Davis
你的分配是否有可能失败(返回null)?你为JVM分配了多少内存?在调用setByteArrayRegion之前,请检查这些指针是否为空。如果是,打印一些内容,写入日志或抛出异常。bad_alloc是在第一个JNI调用后抛出的吗?还是在一堆调用之后?(内存泄漏) - JustinDanielson
可能是你的堆内存不足了。请查看此链接以进行增加:https://dev59.com/lHI_5IYBdhLWcg3wAeLl - JustinDanielson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接