java - Hotspot VM 如何生成字符串oops 和镜像oops?

标签 java jvm hotspot

在openjdk8源代码中,我发现一些java.lang.String oop不经过字节码引擎并由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;
}

如上所述,创建了一个字符串...但是,java.lang.String有五个成员变量(字段),它们是如何初始化的?换句话说,这些 String 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 实例通过分配例程归零。

关于java - Hotspot VM 如何生成字符串oops 和镜像oops?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47299280/

相关文章:

java - 为什么会出现数组索引越界异常?

java - 让 android 通知打开新 Activity

java - 如何在 Django RESTful API 上解决 Retrofit @POST 上的 404?

java - 是否可以从堆转储中实例化 jvm?

java - 可能需要自定义类加载器的场景?

java - JVM 程序 : class files and internalization, 和执行状态的理论方面

java - Mac OS HSDB HotSpot 调试器无法附加到进程

java - OSGI、Java、Netbeans 和 Swing -> 基本工作示例?

java - 在运行 JVM 兼容程序(Java、Kotlin、Scala 等)时​​,如何更改 JVM 实现(例如 HotSpot、GraalVM、OpenJ9 等)?

ssh - 当前是否可以在( headless (headless)模式)*(无需安装*)安装新软件的情况下将{Raspberry Pi}设置为[Wifi热点]?