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ộ)?
- một phương thức hashCode() hoặc chờ()
- 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!
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