【问题标题】:Memory leak sending array from C++ to Java with JNI使用 JNI 将数组从 C++ 发送到 Java 的内存泄漏
【发布时间】:2014-09-07 12:35:47
【问题描述】:

我在使用 JNI 发送大量从 C++ 到 Java 不断更新的整数数据时遇到问题。数据正确发送到java,但是在java或JNI中存在内存泄漏,但我实际上只是将数据处理到一个新的int数组,所以我不知道错误在哪里。

int * intArray = new int [frame_size];

int * getData(){
      return intArray;
 }

这是 JNI 代码

JNIEXPORT jintArray JNICALL Java_JNIData_InData_getData
(JNIEnv * env, jobject obj)
{
    Data* dataOut;

    jclass cls = env->GetObjectClass(obj);
    jfieldID fid = env->GetFieldID(cls, "ptr", "J");
    dataOut = (Data *) env->GetLongField(obj, fid);

    jintArray buffer = env->NewIntArray(frame_size);
    env->SetIntArrayRegion(buffer, 0, frame_size, (const jint *)dataOut->getData());

    env->DeleteLocalRef(cls);
    return buffer;
}

在java中我只有以下代码:

void processData(){
   int [] val = getData();
}

如果我评论getData(),则没有内存泄漏。我想我必须在 C++ 中做数组的指针,有什么建议吗?

【问题讨论】:

  • 当然会泄漏内存。如果您要拨打new[],您在哪里拨打delete[]? C++ 不是 Java。

标签: java c++ memory-leaks java-native-interface


【解决方案1】:

在 C++ 中,您正在创建一个新的 int[],但永远不会删除它。

试试这个:

int *pIntArray = getData();
env->SetIntArrayRegion(buffer, 0, frame_size, (const jint *) pIntArray );
delete[] pIntArray;

【讨论】:

  • 这个问题是,如果由于某种原因SetIntArrayRegion 抛出异常,您已经为内存泄漏敞开了大门。最好为此使用 RAII。
  • 对。最好在整个过程中使用智能指针,包括 getData()。
  • 对于 JNI 编码,您几乎不应该使用裸指针,尤其是对于这样的事情。那些 JNI 函数可能会变得不稳定,并且在创建数组字段时很容易出现内存泄漏。
  • 好的,要为此尝试智能指针,当我删除 [] pIntArray 时出现错误,我相信这是因为我正在更新 main 中的数组
  • @PaulMcKenzie JNI 函数不会引发 C++ 异常。但是,他们可以将 JVM 线程置于异常状态,并且应该对其进行检查。因此,无论如何在 C++ 代码中使用 RAII 会很方便控制流。
猜你喜欢
  • 1970-01-01
  • 2010-11-23
  • 1970-01-01
  • 2017-01-09
  • 1970-01-01
  • 2016-08-24
  • 1970-01-01
  • 1970-01-01
  • 2013-09-11
相关资源
最近更新 更多