如何实现Object类(诸如hashCode和内部字段之类的方法)? [英] How is the Object class implemented (methods like hashCode and internal fields)?

查看:112
本文介绍了如何实现Object类(诸如hashCode和内部字段之类的方法)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很好奇Object类是如何实现的.例如

I am curious how is the Object class implemented. For example

  1. hashCode()或wait()方法
  2. 内部状态如何表示. 例如,内在锁或用于存储调用对象的wait()的线程的数据结构.
  1. a method hashCode() or wait()
  2. How is the internal state represented. For instance, an instrinsic lock or the data structure for storing threads that called object's wait().

为了找到这些信息,我下载了OpenJDK的源代码并开始进行深入研究.首先,我遇到的是\ openjdksrc \ jdk \ src \ share \ native \ java \ lang \ Object.c文件,包含以下内容:

In order to find these out, I have downloaded a source of OpenJDK and started to dig in. First thing, I came across was \openjdksrc\jdk\src\share\native\java\lang\Object.c file, containing, among others:

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 []数组定义了Object方法的本机实现之间的映射.因此,例如,对象的hashCode()映射到JVM_IHashCode函数. JVM_IHashCode在\ openjdksrc \ hotspot \ src \ share \ vm \ prims \ jvm.cpp中实现.这是我的第一个问题. 为什么这已经是VM本身的一部分(已在\ openjdksrc \ hotspot \ src \ share \ vm中定义)? 但是,让我们转到JVM_IHashCode的代码:

and to my understanding, methods[] array defines a mapping between the native implementations of Object's methods. So for example, Object's hashCode() is mapped to JVM_IHashCode function. The JVM_IHashCode is implemented in \openjdksrc\hotspot\src\share\vm\prims\jvm.cpp. And here is my first question. Why this is already a part of VM itself (it is defined already in \openjdksrc\hotspot\src\share\vm)? But lets move to the code of 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

为什么如果object为null,我们在这里返回0?我猜应该抛出NPE.否则,从\ openjdksrc \ hotspot \ src \ share \ vm \ runtime \ synchronizer.cpp中调用FastHashCode,最终在某个时间点调用get_next_hash来计算实际值. 计算后,问题是将其存储在哪里?

Why if object is null we return here 0? I guess an NPE should be thrown. Otherwise, the FastHashCode is called from \openjdksrc\hotspot\src\share\vm\runtime\synchronizer.cpp and eventually at some point of time, the get_next_hash is called that calculates the real value. Once it is calculated the question is where it is stored?

    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我找不到这些类/结构.我只能找到的是:

So the oop class/struct (?) has a markOop class/struct (?) where the hash value is stored. Funilly I can't locate these classes/structs. All I was able to find was:

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

在\ openjdksrc \ hotspot \ src \ share \ vm \ oops \ oop.hpp中 似乎在私有领域中有markOop. 但是在其余的代码中,"oop"到底是什么呢?在哪里可以找到markOop定义?我找到了一个对应的:

in \openjdksrc\hotspot\src\share\vm\oops\oop.hpp which seems to have markOop in a private field. But then what really is "oop" which is refered in the rest of the code? And where to find markOop definition? I have found a corresponding:

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

在\ openjdksrc \ hotspot \ src \ share \ vm \ oops \ markOop.hpp中的

,但是它仅包含枚举,无法找到可以存储哈希值的字段. 如果有人可以回答我的至少一部分问题,我将不胜感激.谢谢!

in \openjdksrc\hotspot\src\share\vm\oops\markOop.hpp but it is only full of enums and can't find a field where the hash value can be stored. If someone could answer at least a part of my questions I would be very grateful. Thanks!

推荐答案

Java对象的哈希码一经计算就存储在对象标头中.

Java object's hash code is stored in object header, once it's calculated.

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

from 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)
//

这篇关于如何实现Object类(诸如hashCode和内部字段之类的方法)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆