2012-12-08 30 views
8

Tôi tò mò làm thế nào là lớp Object thực hiện. Ví dụLớp Object được triển khai như thế nào (các phương thức như hashCode và các trường nội bộ)?

  1. một phương thức hashCode() hoặc chờ()
  2. thế nào là trạng thái nội bộ đại diện. Ví dụ, một khóa công cụ hoặc cấu trúc dữ liệu để lưu trữ các chủ đề gọi là wait() của đối tượng.

Để tìm ra những điều này, tôi đã tải xuống một nguồn OpenJDK và bắt đầu đào sâu. Điều đầu tiên tôi gặp là \ openjdksrc \ jdk \ src \ share \ native \ java \ lang \ Object. tập tin c, chứa, trong số những người khá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); 
    } 
} 

và hiểu biết của tôi, phương pháp [] array định nghĩa một ánh xạ giữa việc triển khai nguồn gốc của phương pháp đối tượng của. Ví dụ, hàm hashCode() của Object được ánh xạ tới hàm JVM_IHashCode. JVM_IHashCode được triển khai trong \ openjdksrc \ hotspot \ src \ share \ vm \ prims \ jvm.cpp. Và đây là câu hỏi đầu tiên của tôi. Tại sao điều này đã là một phần của VM chính nó (nó được định nghĩa đã có trong \ openjdksrc \ hotspot \ src \ share \ vm)? Nhưng cho phép chuyển sang mã của 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 

Tại sao nếu đối tượng là null chúng tôi trở về đây 0? Tôi đoán một NPE nên được ném. Nếu không, FastHashCode được gọi từ \ openjdksrc \ hotspot \ src \ share \ vm \ runtime \ synchronizer.cpp và cuối cùng tại một số thời điểm, get_next_hash được gọi là tính toán giá trị thực. Khi tính toán câu hỏi là câu hỏi được lưu trữ ở đâu?

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; 
    } 

Vì vậy, các oop lớp/struct (?) có một lớp markOop/struct (?), nơi các giá trị hash được lưu trữ. Funilly Tôi không thể xác định các lớp/cấu trúc này. Tất cả tôi đã có thể tìm thấy là:

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

trong \ openjdksrc \ hotspot \ src \ share \ vm \ oops \ oop.hpp mà dường như có markOop trong một lĩnh vực tư nhân. Nhưng sau đó những gì thực sự là "oop" được đề cập trong phần còn lại của mã? Và nơi để tìm định nghĩa markOop? Tôi đã tìm thấy một tương ứng:

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

trong \ openjdksrc \ hotspot \ src \ share \ vm \ oops \ markOop.hpp nhưng nó chỉ là đầy đủ của sự đếm và không thể tìm thấy một lĩnh vực nơi mà các giá trị băm có thể được lưu trữ. Nếu ai đó có thể trả lời ít nhất một phần trong số câu hỏi của tôi Tôi sẽ rất biết ơn. Cảm ơn!

+0

HashCode của 'null' thực sự phải là số không: http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/System.html#identityHashCode (java.lang.Object) – int3

Trả lời

2

Mã băm của đối tượng Java được lưu trữ trong tiêu đề đối tượng, khi được tính toán.

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

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

từ 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) 
// 
+1

Để tham khảo: "OOP" ở đây có nghĩa là "Con trỏ đối tượng thông thường". –

+0

Cảm ơn! Một vài câu hỏi khác xuất hiện trong đầu tôi. Tôi đọc trên trang web bạn đang đề cập rằng tiêu đề đối tượng mất 8 byte. Ở đây có vẻ như nó là 16 byte (4 byte mỗi dòng * 4 dòng). Tôi cũng tò mò về kích thước của một số lĩnh vực. Tại sao băm chỉ có 25 bit? Và tại sao khóa là 2 bit? Tôi nghĩ rằng nó sẽ là đủ để có chỉ 1 bit cho khóa. Và các lĩnh vực: tuổi tác, thời đại và promo_bits là gì? – Janek

+0

@ Janek, câu hỏi hay. Tôi nghĩ rằng các trạng thái đối tượng "bình thường" và "thiên vị" được loại trừ lẫn nhau. và cũng cho "CMD miễn phí" và "CMS được quảng bá". Tuổi được sử dụng để thực hiện quản lý bộ nhớ dựa trên thế hệ. epoch? promo_bits? Tôi không biết. tất cả các câu trả lời là trong mã nguồn. :) – whunmr

Các vấn đề liên quan