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 インクルード ファイルは、これが正しい仮定であることを示しているようですが、この仮定を裏付ける Web 上の情報はあまり見つかりません。

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

バックグラウンド:

突き止めようとしているメモリ リークのある JNI コードがいくつかあります。プロセスの合計サイズは増え続けていますが、JConsole によると、JVM のヒープ メモリの使用量と非ヒープの使用量はほぼ一定のままです。したがって、リークは生の C++ 自体、または JNI コードにあるに違いないというのが私の結論です。

4

1 に答える 1

3

あなたの質問に答えるために、yesjbyteArrayはajobjectであり、yesは、を呼び出すことによってGCにそれを解放するように明示的に指示することができますDeleteLocalRef。そうしないと、現在のJNI呼び出しがJVMに戻ったときに自動的に解放されます。しかし、私はそれがあなたを助けるとは思わない。を使用してNewByteArrayネイティブメモリではなくJVMヒープNewDirectByteBufferを割り当てます。そうでなければ、GCはそれに到達できませんでした(そして呼び出しは意味がありません)。しかし、JVMヒープの使用量はかなり一定であるとあなたは言います。Javaプロセスのメモリ使用量が増加しているが、JVMヒープが増加していない場合は、ネイティブ割り当てに問題があります。あなたはどこにいますかDeleteLocalRefdataPtrから来る?適切に割り当てを解除しましたか?「長時間実行されるコード」に他の重要な割り当てはありませんか?必ずしもJNIに関連付けられているわけではありません...

于 2012-12-11T21:46:11.443 に答える