なぜSetByteArrayRegion壊れメモリーしていますか?

いくつかの名前:

SetByteArrayRegion関数は次のように実装されています

JNI_ENTRY(void, \
jni_Set##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \
             jsize len, const ElementType *buf)) \
  JNIWrapper("Set" XSTR(Result) "ArrayRegion"); \
  DTRACE_PROBE5(hotspot_jni, Set##Result##ArrayRegion__entry, env, array, start, len, buf);\
  DT_VOID_RETURN_MARK(Set##Result##ArrayRegion); \
  typeArrayOop dst = typeArrayOop(JNIHandles::resolve_non_null(array)); \
  if (start < 0 || len < 0 || ((unsigned int)start + (unsigned int)len > (unsigned int)dst->length())) { \
    THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \
  } else { \
    if (len > 0) { \
      int sc = TypeArrayKlass::cast(dst->klass())->log2_element_size(); \
      memcpy((u_char*) dst->Tag##_at_addr(start), \
             (u_char*) buf, \
             len << sc);    \
    } \
  } \
JNI_END

それが呼び出しを観察することができるmemcpyJavaヒープの配列へのポインタネイティブに:dst->Tag##_at_addr(start)memcpy自身私は何もの真ん中に配列を移動するGCを停止しないと結論付けてアトミックではありませんmemcpyコール。

また、アレイは、右後somwhere移動させることができるdst->Tag##_at_addr(start)再び原因メモリ破損。

契約では、「重要な」方法が採用しますGC_locker::lock_critical(thread);

なぜあるSetArrayRegion方法で安全ですか?私は何を取りこぼしたか?

apangin:

あなたが見ることができるように、関数がに包まれているJNI_ENTRY順番に実行され、マクロThreadInVMfromNative状態遷移を。この手段は、Javaスレッドが実行SetByteArrayRegion中であることが保証されている_thread_in_vm状態。

非同時圧縮コレクタは唯一のグローバルセーフポイントでオブジェクトを移動することができます。セーフポイントは、すべてのJavaスレッドがいずれかのブロックまたはネイティブコード(実行されていることを意味する_thread_in_native状態)。

一方、セーフポイントが要求されるのであれば、SetByteArrayRegion実行されている、JVMは、すべてのスレッド完全な現在のVM操作するまで待機します。場合Сontrariwiseは、SetByteArrayRegionGCが動作している間に実行され、スレッドは、GCが完了するまでの状態遷移でブロックします。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=232823&siteId=1