2

直接ByteBufferをJNIに返す場合、JVM / GCによって再利用できるようになるまでどのくらいかかりますか?

次のような関数があるとします。

void* func()
{
  [ ... ]
  jobject result = env->CallStaticObjectMethod(testClass, doSomethingMethod);
  void* pointerToMemory = env->GetDirectBufferAddress(result);
  return pointerToMemory;

}

JVMは、私がそれをどのくらいの期間使用するのかをおそらく知ることができませんよpointerToMemoryね?そのアドレスと対応するメモリをしばらく保持したい場合はどうなりますか?

この問題を回避し、次のようにJavaからJNIにbyte[]を返したいとします。

ByteBuffer buf;
byte[] b = new byte[1000];
buf = ByteBuffer.wrap(b);
buf.order(ByteOrder.BIG_ENDIAN); 

return buf.array();

そして、上記と同じように、そのbyte []へのポインタを格納し、しばらくそれを保持したいと思います。どのように/いつ/なぜJVMはJavaからのバッキングbyte[]の後に来るのでしょうか?

void* function()
{
  jbyteArray byteArr = (jbytearray)env->CallStaticObjectMethod(testClass, doSomethingMethod);
  jbyte *b= env->GetByteArrayElements(byteArr, 0);  
  return b;
}
4

1 に答える 1

1

簡単な答えは次のとおりです。関数がネイティブメソッドを実装している場合、戻るとすぐにポインタは無効になります。

これを回避するには、戻った後に有効に保つ予定のすべてのオブジェクトのグローバル参照を取得する必要があります。詳細については、ローカルおよびグローバルリファレンスに関するドキュメントを参照してください。

JNIがネイティブコードからの参照を管理する方法をよりよく理解するには、PushLocalFrame/PopLocalFrameのドキュメントを参照してください。

于 2013-03-01T12:13:38.513 に答える