9

Object クラスがどのように実装されているのか興味があります。例えば

  1. メソッド hashCode() または wait()
  2. 内部状態はどのように表されますか。たとえば、固有のロックや、オブジェクトの wait() を呼び出したスレッドを格納するためのデータ構造です。

これらを見つけるために、私は OpenJDK のソースをダウンロードし、掘り下げ始めました。最初に出会ったのは、\openjdksrc\jdk\src\share\native\java\lang\Object.c ファイルで、その他:

static JNINativeMethod methods[] = {
    {"hashCode",    "()I",                    (void *)&JVM_IHashCode},
    {"wait",        "(J)V",                   (void *)&JVM_MonitorWait},
    {"notify",      "()V",                    (void *)&JVM_MonitorNotify},
    {"notifyAll",   "()V",                    (void *)&JVM_MonitorNotifyAll},
    {"clone",       "()Ljava/lang/Object;",   (void *)&JVM_Clone},
};
JNIEXPORT void JNICALL
Java_java_lang_Object_registerNatives(JNIEnv *env, jclass cls)
{
    (*env)->RegisterNatives(env, cls,
                            methods, sizeof(methods)/sizeof(methods[0]));
}

JNIEXPORT jclass JNICALL
Java_java_lang_Object_getClass(JNIEnv *env, jobject this)
{
    if (this == NULL) {
        JNU_ThrowNullPointerException(env, NULL);
        return 0;
    } else {
        return (*env)->GetObjectClass(env, this);
    }
}

私の理解では、methods[] 配列は、オブジェクトのメソッドのネイティブ実装間のマッピングを定義します。たとえば、オブジェクトの hashCode() は JVM_IHashCode 関数にマップされます。JVM_IHashCode は、\openjdksrc\hotspot\src\share\vm\prims\jvm.cpp に実装されています。そして、これが私の最初の質問です。これがすでに VM 自体の一部になっているのはなぜですか (\openjdksrc\hotspot\src\share\vm で既に定義されています)。 しかし、JVM_IHashCode のコードに移りましょう。

JVM_ENTRY(jint, JVM_IHashCode(JNIEnv* env, jobject handle))
  JVMWrapper("JVM_IHashCode");
  // as implemented in the classic virtual machine; return 0 if object is NULL
  return handle == NULL ? 0 : ObjectSynchronizer::FastHashCode (THREAD, JNIHandles::resolve_non_null(handle)) ;
JVM_END

オブジェクトが null の場合、ここで 0 を返すのはなぜですか? NPEを投げるべきだと思います。それ以外の場合は、FastHashCode が \openjdksrc\hotspot\src\share\vm\runtime\synchronizer.cpp から呼び出され、最終的にある時点で、実際の値を計算する get_next_hash が呼び出されます。 それが計算されたら、問題はそれがどこに保存されているかです。

    intptr_t ObjectSynchronizer::FastHashCode (Thread * Self, oop obj) {

...CUT...

      ObjectMonitor* monitor = NULL;
      markOop temp, test;
      intptr_t hash;
      markOop mark = ReadStableMark (obj);

...CUT...

      if (mark->is_neutral()) {
        hash = mark->hash();              // this is a normal header
        if (hash) {                       // if it has hash, just return it
          return hash;
        }
        hash = get_next_hash(Self, obj);  // allocate a new hash code
        temp = mark->copy_set_hash(hash); // merge the hash code into header
        // use (machine word version) atomic operation to install the hash
        test = (markOop) Atomic::cmpxchg_ptr(temp, obj->mark_addr(), mark);
        if (test == mark) {
          return hash;
        }
        // If atomic operation failed, we must inflate the header
        // into heavy weight monitor. We could add more code here
        // for fast path, but it does not worth the complexity.
      } 
...CUT...
      return hash;
    }

したがって、oop クラス/構造体( ? ) には、ハッシュ値が格納されるmarkOop クラス/構造体 ( ? ) があります。Funilly 私はこれらのクラス/構造体を見つけることができません。私が見つけることができたのは次のとおりです。

class oopDesc {
  friend class VMStructs;
 private:
  volatile markOop  _mark;
...CUT...

\openjdksrc\hotspot\src\share\vm\oops\oop.hpp には、プライベート フィールドに markOop があるようです。しかし、コードの残りの部分で参照されている「oop」とは実際には何なのでしょうか? また、markOop の定義はどこにありますか? 対応するものを見つけました:

class markOopDesc: public oopDesc 
...CUT...

\openjdksrc\hotspot\src\share\vm\oops\markOop.hpp にありますが、列挙型でいっぱいで、ハッシュ値を格納できるフィールドが見つかりません。誰かが私の質問の少なくとも一部に答えることができれば、私はとても感謝しています. ありがとう!

4

1 に答える 1

2

Java オブジェクトのハッシュ コードは、計算されると、オブジェクト ヘッダーに格納されます。

http://www.javamex.com/tutorials/memory/object_memory_usage.shtml

http://hunmr.blogspot.com/2012/08/java-performance-tunning.html

hotspot/src/share/vm/oops/markOop.hpp から

// The markOop describes the header of an object.
//
// Note that the mark is not a real oop but just a word.
// It is placed in the oop hierarchy for historical reasons.
//
// Bit-format of an object header (most significant first, big endian layout below):
//
//  32 bits:
//  --------
//             hash:25 ------------>| age:4    biased_lock:1 lock:2 (normal object)
//             JavaThread*:23 epoch:2 age:4    biased_lock:1 lock:2 (biased object)
//             size:32 ------------------------------------------>| (CMS free block)
//             PromotedObject*:29 ---------->| promo_bits:3 ----->| (CMS promoted object)
//
于 2012-12-08T14:16:44.497 に答える