2017-11-15 16 views
0

openjdk8 소스 코드에서 일부 java.lang.String oop은 바이트 코드 엔진을 거치지 않고 jvm 자체에서 할당한다는 것을 알았습니다. hotspot/src/share/vm/classfile/javaClasses.cpp:185는 말하기를 :핫스팟 VM은 String oops 및 mirror oops를 어떻게 생성합니까?

위와
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 다섯 개 멤버 변수 (필드), 그들이 어떻게 초기화합니까있다? 다른 말로하면, 이것들은 어떻게합니까 가짜 문자열은 진짜 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.Stringjava.lang.Class의 다른 필드는 언제 oop에 채워 집니까? 고맙습니다.

+2

Java 8부터는 인스턴스 필드가 두 개뿐입니다. 다른 필드는 '정적'입니다. 'hashCode'가'hashCode()'메소드 내에서 느리게 초기화되기 때문에'char [] value'는 초기화 될 필요가있는 유일한 필드입니다. – Holger

+0

감사! 나는 그것을 완전히 이해한다. – wind2412

답변

2

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 필드가 느리게 산출된다. 할당 시간에 이 있으므로 allocate_instance은 전체 개체를 지 웁니다. String 인스턴스 필드는 JDK 8에 없습니다.

java.lang.Class에 대해서는 모든 필드가 일종의 캐시이기 때문에 할당시 초기화 할 필드가 없습니다. 필요시 Java 코드로 설정됩니다. 다시, 전체 Class 인스턴스는 할당 루틴에 의해 0으로 설정됩니다.

+0

고마워! 나는'java.lang.Class'가 하나의 사소한 생성자만을 가지고 있음을 발견했다. 'java.lang.String'은 하나의'char []'생성자를 가지고 있고'StringTable :: intern'은'TypeArrayOop'을 삽입합니다. – wind2412