在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代码中。
答案 0 :(得分:3)
要回答您的问题,是jbyteArray
是jobject
,是的,您可以通过致电DeleteLocalRef
明确告诉GC释放它。否则,当前JNI调用返回到JVM时,它将自动释放。 但我不认为它会对你有所帮助。通过使用NewByteArray
和NewDirectByteBuffer
,您将分配 JVM堆,而不是本机内存。它一定是这样,否则GC无法到达它(并且调用DeleteLocalRef
没有意义)。但是你说JVM堆的使用是相当稳定的。如果java进程内存使用量增长但不是JVM堆,那么你的原生分配就会出现问题。你的dataPtr
来自哪里?你正确地解除了它吗?在“长时间运行的代码”中是否还有其他重要的分配?根本不一定与JNI联系在一起......