Hotspot虚拟机如何产生String oops和mirror oops?
How do String oops and mirror oops generate by Hotspot VM?
在openjdk8源码中,我发现有些java.lang.Stringoop没有经过字节码引擎,而是jvm自己分配的。正如 hotspot/src/share/vm/classfile/javaClasses.cpp:185
所说:
Handle java_lang_String::create_from_unicode(jchar* unicode, int length, TRAPS) {
Handle h_obj = basic_create(length, CHECK_NH); // alloc size of java.lang.String oop
typeArrayOop buffer = value(h_obj());
for (int index = 0; index < length; index++) {
buffer->char_at_put(index, unicode[index]); // put a char[] into this oop...
}
return h_obj;
}
如上,创建了一个fake字符串……但是,java.lang.String
有五个成员变量(字段),它们是如何初始化的呢?也就是说,这些fakeString oop是如何变成真正的java.lang.String
对象的?
和java.lang.String
一样,java.lang.Class
也是这样做的。在 hotspot/src/share/vm/classfile/javaClasses.cpp:553
说:
oop java_lang_Class::create_mirror(KlassHandle k, Handle protection_domain, TRAPS) {
...
Handle mirror = InstanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK_0);
...
// if `k` holds a InstanceKlass, it will initialize the static fields by constant value attribute. else do nothing...
}
我对此很困惑。只有alloc
内存,如果是java.lang.String
的对象,就放一个char[]
进去;但是 java.lang.String
和 java.lang.Class
中的其他字段何时填充到 oop 中?谢谢。
java_lang_String::basic_create()
分配 String
对象并初始化其 value
字段:
obj = InstanceKlass::cast(SystemDictionary::String_klass())->allocate_instance(CHECK_NH);
// Create the char array. The String object must be handlized here
// because GC can happen as a result of the allocation attempt.
Handle h_obj(THREAD, obj);
typeArrayOop buffer;
buffer = oopFactory::new_charArray(length, CHECK_NH);
// Point the String at the char array
obj = h_obj();
set_value(obj, buffer); <<<--- char[] value is set here
// No need to zero the offset, allocation zero'ed the entire String object
assert(offset(obj) == 0, "initial String offset should be zero");
//set_offset(obj, 0);
set_count(obj, length);
hash
字段是延迟计算的。在分配时,它具有默认值 0
,因为 allocate_instance
会清除整个对象。 JDK 8.
中没有其他 String
个实例字段
至于java.lang.Class
,它没有在分配时初始化的字段,因为它的所有字段都是一种缓存。它们在需要时设置在 Java 代码中。同样,整个 Class
实例由分配例程清零。
在openjdk8源码中,我发现有些java.lang.Stringoop没有经过字节码引擎,而是jvm自己分配的。正如 hotspot/src/share/vm/classfile/javaClasses.cpp:185
所说:
Handle java_lang_String::create_from_unicode(jchar* unicode, int length, TRAPS) {
Handle h_obj = basic_create(length, CHECK_NH); // alloc size of java.lang.String oop
typeArrayOop buffer = value(h_obj());
for (int index = 0; index < length; index++) {
buffer->char_at_put(index, unicode[index]); // put a char[] into this oop...
}
return h_obj;
}
如上,创建了一个fake字符串……但是,java.lang.String
有五个成员变量(字段),它们是如何初始化的呢?也就是说,这些fakeString oop是如何变成真正的java.lang.String
对象的?
和java.lang.String
一样,java.lang.Class
也是这样做的。在 hotspot/src/share/vm/classfile/javaClasses.cpp:553
说:
oop java_lang_Class::create_mirror(KlassHandle k, Handle protection_domain, TRAPS) {
...
Handle mirror = InstanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK_0);
...
// if `k` holds a InstanceKlass, it will initialize the static fields by constant value attribute. else do nothing...
}
我对此很困惑。只有alloc
内存,如果是java.lang.String
的对象,就放一个char[]
进去;但是 java.lang.String
和 java.lang.Class
中的其他字段何时填充到 oop 中?谢谢。
java_lang_String::basic_create()
分配 String
对象并初始化其 value
字段:
obj = InstanceKlass::cast(SystemDictionary::String_klass())->allocate_instance(CHECK_NH);
// Create the char array. The String object must be handlized here
// because GC can happen as a result of the allocation attempt.
Handle h_obj(THREAD, obj);
typeArrayOop buffer;
buffer = oopFactory::new_charArray(length, CHECK_NH);
// Point the String at the char array
obj = h_obj();
set_value(obj, buffer); <<<--- char[] value is set here
// No need to zero the offset, allocation zero'ed the entire String object
assert(offset(obj) == 0, "initial String offset should be zero");
//set_offset(obj, 0);
set_count(obj, length);
hash
字段是延迟计算的。在分配时,它具有默认值 0
,因为 allocate_instance
会清除整个对象。 JDK 8.
String
个实例字段
至于java.lang.Class
,它没有在分配时初始化的字段,因为它的所有字段都是一种缓存。它们在需要时设置在 Java 代码中。同样,整个 Class
实例由分配例程清零。