3

在 JNI 中,jbyteArray 是否被视为作业?即:如果我有一些长时间运行的 C++ 代码,我可以使用如下代码来释放对象引用吗?

JNIEnv* env;

jobject getJavaObj(bool useArray) {
    if (useArray) {
        jbyteArray dataArray = env->NewByteArray(getDataSize());
        env->SetByteArrayRegion(dataArray, 0, getDataSize(), dataPtr);
        return static_cast<jobject>(dataArray)
    } else {
        jobject javaByteBuffer = env->NewDirectByteBuffer(dataPtr, getDataSize());
        return javaByteBuffer;
    }
}

// ...
jobject theData = getJavaObj(true);
// ... Code to use theData jobject goes here...
env->DeleteLocalRef(theData); // Will this cause any issues?

JDK 的 jni.h 包含文件似乎表明这将是一个正确的假设,但我在网上找不到太多来支持这个假设:

#ifdef __cplusplus
class _jobject {};
...
class _jarray : public _jobject {};
typedef _jbyteArray *jbyteArray;
#else
....
#endif

背景:

我有一些 JNI 代码存在内存泄漏,我正试图确定它。总进程大小不断增加,但 JConsole 表示 JVM 的堆内存使用和非堆使用保持相当稳定。所以我的结论是泄漏必须在原始 C++ 本身或 JNI 代码中。

4

1 回答 1

3

要回答您的问题,是jbyteArrayjobject,是的,您可以通过调用明确告诉 GC 释放它DeleteLocalRef。否则,当当前 JNI 调用返回 JVM 时,它会自动释放。但我不认为它会帮助你。通过使用NewByteArrayNewDirectByteBuffer您分配的是JVM 堆,而不是本机内存。必须如此,否则 GC 无法到达它(并且调用DeleteLocalRef没有意义)。但是你说 JVM 堆的使用是相当稳定的。如果 java 进程内存使用量正在增长,但 JVM 堆没有增长,那么您的本机分配有问题。你在哪里dataPtr来自(哪里?你是否正确地释放它?您的“长时间运行的代码”中没有其他重要的分配吗?根本不一定与JNI相关......

于 2012-12-11T21:46:11.443 回答