jvm源码解读--02 Array<u1>* tags = MetadataFactory::new_writeable_array<u1>(loader_data, length, 0, CHECK_NULL); 函数引入的jvm内存分配解析
current路径:
#0 Array<unsigned char>::operator new (size=8, loader_data=0x7fd4c802e868, length=87, read_only=false, __the_thread__=0x7fd4c800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/utilities/array.hpp:324 #1 0x00007fd4cebf27ba in MetadataFactory::new_writeable_array<unsigned char> (loader_data=0x7fd4c802e868, length=87, __the_thread__=0x7fd4c800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/memory/metadataFactory.hpp:52 #2 0x00007fd4cebf2537 in MetadataFactory::new_writeable_array<unsigned char> (loader_data=0x7fd4c802e868, length=87, value=0 '\000', __the_thread__=0x7fd4c800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/memory/metadataFactory.hpp:57 #3 0x00007fd4cebe9a95 in ConstantPool::allocate (loader_data=0x7fd4c802e868, length=87, __the_thread__=0x7fd4c800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/oops/constantPool.cpp:47 #4 0x00007fd4ceb28bbc in ClassFileParser::parse_constant_pool (this=0x7fd4d06f2010, __the_thread__=0x7fd4c800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/classFileParser.cpp:331 #5 0x00007fd4ceb34e84 in ClassFileParser::parseClassFile (this=0x7fd4d06f2010, name=0x7fd4cc1050e8, loader_data=0x7fd4c802e868, protection_domain=..., host_klass=..., cp_patches=0x0, parsed_name=..., verify=false, __the_thread__=0x7fd4c800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/classFileParser.cpp:3774 #6 0x00007fd4ceb439b5 in ClassFileParser::parseClassFile (this=0x7fd4d06f2010, name=0x7fd4cc1050e8, loader_data=0x7fd4c802e868, protection_domain=..., parsed_name=..., verify=false, __the_thread__=0x7fd4c800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/classFileParser.hpp:468 #7 0x00007fd4ceb417cb in ClassLoader::load_classfile (h_name=0x7fd4cc1050e8, __the_thread__=0x7fd4c800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/classLoader.cpp:931 #8 0x00007fd4cf181903 in SystemDictionary::load_instance_class (class_name=0x7fd4cc1050e8, class_loader=..., __the_thread__=0x7fd4c800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/systemDictionary.cpp:1304 #9 0x00007fd4cf17fced in SystemDictionary::resolve_instance_class_or_null (name=0x7fd4cc1050e8, class_loader=..., protection_domain=..., __the_thread__=0x7fd4c800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/systemDictionary.cpp:779 #10 0x00007fd4cf17e6be in SystemDictionary::resolve_or_null (class_name=0x7fd4cc1050e8, class_loader=..., protection_domain=..., __the_thread__=0x7fd4c800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/systemDictionary.cpp:232 #11 0x00007fd4cf17e12f in SystemDictionary::resolve_or_fail (class_name=0x7fd4cc1050e8, class_loader=..., protection_domain=..., throw_error=true, __the_thread__=0x7fd4c800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/systemDictionary.cpp:171 #12 0x00007fd4cf17e451 in SystemDictionary::resolve_or_fail (class_name=0x7fd4cc1050e8, throw_error=true, __the_thread__=0x7fd4c800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/systemDictionary.cpp:212 #13 0x00007fd4cf18327b in SystemDictionary::initialize_wk_klass (id=SystemDictionary::Object_klass_knum, init_opt=0, __the_thread__=0x7fd4c800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/systemDictionary.cpp:1866 #14 0x00007fd4cf18339e in SystemDictionary::initialize_wk_klasses_until (limit_id=SystemDictionary::Cloneable_klass_knum, start_id=@0x7fd4d06f29ec: SystemDictionary::Object_klass_knum, __the_thread__=0x7fd4c800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/systemDictionary.cpp:1882 #15 0x00007fd4cf186b86 in SystemDictionary::initialize_wk_klasses_through (end_id=SystemDictionary::Class_klass_knum, start_id=@0x7fd4d06f29ec: SystemDictionary::Object_klass_knum, __the_thread__=0x7fd4c800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/systemDictionary.hpp:408 #16 0x00007fd4cf1834d0 in SystemDictionary::initialize_preloaded_classes (__the_thread__=0x7fd4c800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/systemDictionary.cpp:1901 #17 0x00007fd4cf18319d in SystemDictionary::initialize (__the_thread__=0x7fd4c800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/systemDictionary.cpp:1843 #18 0x00007fd4cf1d41d1 in Universe::genesis (__the_thread__=0x7fd4c800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/memory/universe.cpp:288 #19 0x00007fd4cf1d6439 in universe2_init () at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/memory/universe.cpp:991 #20 0x00007fd4ced6fa5c in init_globals () at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/runtime/init.cpp:114 #21 0x00007fd4cf1b7756 in Threads::create_vm (args=0x7fd4d06f2e40, canTryAgain=0x7fd4d06f2dff) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/runtime/thread.cpp:3424 #22 0x00007fd4cee22232 in JNI_CreateJavaVM (vm=0x7fd4d06f2e88, penv=0x7fd4d06f2e80, args=0x7fd4d06f2e40) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/prims/jni.cpp:5166 #23 0x00007fd4d00bf780 in InitializeJVM (pvm=0x7fd4d06f2e88, penv=0x7fd4d06f2e80, ifn=0x7fd4d06f2e90) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/jdk/src/share/bin/java.c:1145 #24 0x00007fd4d00bd6f9 in JavaMain (_args=0x7ffdde8bac20) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/jdk/src/share/bin/java.c:371 #25 0x00007fd4d02d9ea5 in start_thread () from /lib64/libpthread.so.0 #26 0x00007fd4cfbe29fd in clone () from /lib64/libc.so.6
进入这个函数
void* operator new(size_t size, ClassLoaderData* loader_data, int length, bool read_only, TRAPS) throw() { size_t word_size = Array::size(length); return (void*) Metaspace::allocate(loader_data, word_size, read_only, MetaspaceObj::array_type(sizeof(T)), CHECK_NULL); }
说明length= word_size=12,进入标橘子的函数,解释一下这个T为u1,能看到为case1
static MetaspaceObj::Type array_type(size_t elem_size) { //elem_size=1
switch (elem_size) {
case 1: return TypeArrayU1Type; //这个
case 2: return TypeArrayU2Type;
case 4: return TypeArrayU4Type;
case 8: return TypeArrayU8Type;
default:
return TypeArrayOtherType;
}
}
进入主函数
MetaWord* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size, //word_size=12 bool read_only, MetaspaceObj::Type type, TRAPS) { //参数type= TypeArrayU1Type if (HAS_PENDING_EXCEPTION) { assert(false, "Should not allocate with exception pending"); return NULL; // caller does a CHECK_NULL too } assert(loader_data != NULL, "Should never pass around a NULL loader_data. " "ClassLoaderData::the_null_class_loader_data() should have been used."); // Allocate in metaspaces without taking out a lock, because it deadlocks // with the SymbolTable_lock. Dumping is single threaded for now. We'll have // to revisit this for application class data sharing. if (DumpSharedSpaces) { //不进入 assert(type > MetaspaceObj::UnknownType && type < MetaspaceObj::_number_of_types, "sanity"); Metaspace* space = read_only ? loader_data->ro_metaspace() : loader_data->rw_metaspace(); MetaWord* result = space->allocate(word_size, NonClassType); if (result == NULL) { report_out_of_shared_space(read_only ? SharedReadOnly : SharedReadWrite); } space->record_allocation(result, type, space->vsm()->get_raw_word_size(word_size)); // Zero initialize. Copy::fill_to_aligned_words((HeapWord*)result, word_size, 0); return result; } MetadataType mdtype = (type == MetaspaceObj::ClassType) ? ClassType : NonClassType; //这里mdtype= NonClassType // Try to allocate metadata. MetaWord* result = loader_data->metaspace_non_null()->allocate(word_size, mdtype); if (result == NULL) { // Allocation failed. if (is_init_completed()) { // Only start a GC if the bootstrapping has completed. // Try to clean out some memory and retry. result = Universe::heap()->collector_policy()->satisfy_failed_metadata_allocation( loader_data, word_size, mdtype); } } if (result == NULL) { report_metadata_oome(loader_data, word_size, mdtype, CHECK_NULL); } // Zero initialize. Copy::fill_to_aligned_words((HeapWord*)result, word_size, 0); return result; }
进入主函数,标记为黄色的
Metaspace* ClassLoaderData::metaspace_non_null() { assert(!DumpSharedSpaces, "wrong metaspace!"); // If the metaspace has not been allocated, create a new one. Might want // to create smaller arena for Reflection class loaders also. // The reason for the delayed allocation is because some class loaders are // simply for delegating with no metadata of their own. if (_metaspace == NULL) { //不为0 直接返回 MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag); // Check again if metaspace has been allocated while we were getting this lock. if (_metaspace != NULL) { return _metaspace; } if (this == the_null_class_loader_data()) { assert (class_loader() == NULL, "Must be"); set_metaspace(new Metaspace(_metaspace_lock, Metaspace::BootMetaspaceType)); } else if (is_anonymous()) { if (TraceClassLoaderData && Verbose && class_loader() != NULL) { tty->print_cr("is_anonymous: %s", class_loader()->klass()->internal_name()); } set_metaspace(new Metaspace(_metaspace_lock, Metaspace::AnonymousMetaspaceType)); } else if (class_loader()->is_a(SystemDictionary::reflect_DelegatingClassLoader_klass())) { if (TraceClassLoaderData && Verbose && class_loader() != NULL) { tty->print_cr("is_reflection: %s", class_loader()->klass()->internal_name()); } set_metaspace(new Metaspace(_metaspace_lock, Metaspace::ReflectionMetaspaceType)); } else { set_metaspace(new Metaspace(_metaspace_lock, Metaspace::StandardMetaspaceType)); } } return _metaspace; }
元空间 _metaspace
上边直接返回没什么可看的,现在看下这个_metaspace
(gdb) p *_metaspace $2 = (Metaspace) {<CHeapObj<256u>> = {<AllocatedObj> = {_vptr.AllocatedObj = 0x7fd4cfa2c870 <vtable for Metaspace+16>}, <No data fields>}, static _compressed_class_space_size = 0x40000000, //默认大小40M static _first_chunk_word_size = 0x80000, //第一个NonClassType类型的MetaChunk的大小 static _first_class_chunk_word_size = 0xc000, //第一个ClassType类型的MetaChunk的大小 static _commit_alignment = 0x1000, //commit内存的粒度 static _reserve_alignment = 0x1000, //reserve内存的粒度 _vsm = 0x7fd4c8050298, //NonClassType类型的元数据对应的SpaceManager _class_vsm = 0x7fd4c8050328, //ClassType类型的元数据对应的SpaceManager static _space_list = 0x7fd4c802e608, // NonClassType类型的元数据对应的VirtualSpaceList static _class_space_list = 0x7fd4c802e3a8, // ClassType类型的元数据对应的VirtualSpaceList static _chunk_manager_metadata = 0x7fd4c802e778, //NonClassType类型的元数据对应的ChunkManager static _chunk_manager_class = 0x7fd4c802e518, // ClassType类型的元数据对应的ChunkManager _alloc_record_head = 0x0, //AllocRecord链表的头部元素 _alloc_record_tail = 0x0} //AllocRecord链表的尾部元素
这个现在还不太懂,慢慢来吧
进入主函数标橘子色的后半部分_metaspace->allocate(word_size, mdtype);
MetaWord* Metaspace::allocate(size_t word_size, MetadataType mdtype) { // DumpSharedSpaces doesn't use class metadata area (yet) // Also, don't use class_vsm() unless UseCompressedClassPointers is true. if (is_class_space_allocation(mdtype)) {//不成立 return class_vsm()->allocate(word_size); //不进入 } else { return vsm()->allocate(word_size); } }
SpaceManager* vsm() const { return _vsm; }
_vsm的天下,就是_vsm->allocate()
主流程接着看
MetaWord* SpaceManager::allocate(size_t word_size) { MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); size_t raw_word_size = get_raw_word_size(word_size); BlockFreelist* fl = block_freelists(); MetaWord* p = NULL; // Allocation from the dictionary is expensive in the sense that // the dictionary has to be searched for a size. Don't allocate // from the dictionary until it starts to get fat. Is this // a reasonable policy? Maybe an skinny dictionary is fast enough // for allocations. Do some profiling. JJJ if (fl->total_size() > allocation_from_dictionary_limit) { p = fl->get_block(raw_word_size); } if (p == NULL) { p = allocate_work(raw_word_size); } return p; }
进入橘子程序
size_t get_raw_word_size(size_t word_size) { size_t byte_size = word_size * BytesPerWord; size_t raw_bytes_size = MAX2(byte_size, sizeof(Metablock)); //sizeof(Metablock)=24 //返回96 raw_bytes_size = align_size_up(raw_bytes_size, Metachunk::object_alignment()); size_t raw_word_size = raw_bytes_size / BytesPerWord; //返回12 assert(raw_word_size * BytesPerWord == raw_bytes_size, "Size problem"); return raw_word_size; }
查看类结构
class Metablock : public Metabase<Metablock> {
friend class VMStructs;
public:
Metablock(size_t word_size) : Metabase<Metablock>(word_size) {}
};
// Super class of Metablock and Metachunk to allow them to
// be put on the FreeList and in the BinaryTreeDictionary.
template <class T>
class Metabase VALUE_OBJ_CLASS_SPEC {
size_t _word_size;
T* _next;
T* _prev;
protected:
Metabase(size_t word_size) : _word_size(word_size), _next(NULL), _prev(NULL) {}
public:
T* next() const { return _next; }
T* prev() const { return _prev; }
void set_next(T* v) { _next = v; assert(v != this, "Boom");}
void set_prev(T* v) { _prev = v; assert(v != this, "Boom");}
void clear_next() { set_next(NULL); }
void clear_prev() { set_prev(NULL); }
size_t size() const volatile { return _word_size; }
void set_size(size_t v) { _word_size = v; }
void link_next(T* ptr) { set_next(ptr); }
void link_prev(T* ptr) { set_prev(ptr); }
void link_after(T* ptr) {
link_next(ptr);
if (ptr != NULL) ptr->link_prev((T*)this);
}
uintptr_t* end() const { return ((uintptr_t*) this) + size(); }
bool cantCoalesce() const { return false; }
bool verify_chunk_in_free_list(T* tc) const { return true; }
bool verify_par_locked() { return true; }
void assert_is_mangled() const {/* Don't check "\*/}
bool is_free() { return true; }
};
主流程,进入紫色程序
//进入到这个函数 BlockFreelist* fl = block_freelists(); BlockFreelist* block_freelists() const { return (BlockFreelist*) &_block_freelists;
BlockFreelist _block_freelists;
查看内存内容
(gdb) p _block_freelists $4 = {_dictionary = 0x0, static WasteMultiplier = 4}
蓝色上边不执行的if判断
if (fl->total_size() > allocation_from_dictionary_limit) { p = fl->get_block(raw_word_size); } size_t total_size() { if (dictionary() == NULL) { return 0; //执行到这里 } else { return dictionary()->total_size(); } }
进入蓝色程序,这个就是_vsm
// Returns the address of spaced allocated for "word_size". // This methods does not know about blocks (Metablocks) MetaWord* SpaceManager::allocate_work(size_t word_size) { assert_lock_strong(_lock); // Is there space in the current chunk? MetaWord* result = NULL; // For DumpSharedSpaces, only allocate out of the current chunk which is // never null because we gave it the size we wanted. Caller reports out // of memory if this returns null. if (DumpSharedSpaces) { //不进入,跳过 assert(current_chunk() != NULL, "should never happen"); inc_used_metrics(word_size); return current_chunk()->allocate(word_size); // caller handles null result } if (current_chunk() != NULL) { //到这里 Metachunk* current_chunk() const { return _current_chunk; } result = current_chunk()->allocate(word_size); //Metachunk* _current_chunk; } if (result == NULL) { result = grow_and_allocate(word_size); } if (result != NULL) { inc_used_metrics(word_size); assert(result != (MetaWord*) chunks_in_use(MediumIndex), "Head of the list is being allocated"); } return result; }
主程序进入灰色的函数,是这个Metachunk的类进行了内存分配
//接着进入 MetaWord* Metachunk::allocate(size_t word_size) { //word_size =12 MetaWord* result = NULL; // If available, bump the pointer to allocate. if (free_word_size() >= word_size) { result = _top; _top = _top + word_size; } return result; }
看下Metachunk对象的内存结构
(gdb) p/x _current_chunk $5 = 0x7fd4b8800000 (gdb) p/x * _current_chunk $6 = {<Metabase<Metachunk>> = {_word_size = 0x80000, _next = 0x0, _prev = 0x0}, _container = 0x7fd4c802e678, _top = 0x7fd4b88000a8, _is_tagged_free = 0x0}
查看Metachunk类的结果
class Metachunk : public Metabase<Metachunk> { friend class TestMetachunk; // The VirtualSpaceNode containing this chunk. VirtualSpaceNode *_container; // Current allocation top. MetaWord *_top; ...省略方法 }
进入黄色函数内部
进入free_word_size() 方法 size_t Metachunk::free_word_size() const { return pointer_delta(end(), _top, sizeof(MetaWord)); }
inline size_t pointer_delta(const void* left,
const void* right,
size_t element_size) {
return (((uintptr_t) left) - ((uintptr_t) right)) / element_size;
}
看的这里就知道了是用_current_chunk的end()-_top地址
// Metachunk - Quantum of allocation from a Virtualspace // Metachunks are reused (when freed are put on a global freelist) and // have no permanent association to a SpaceManager. // +--------------+ <- end --+ --+ 0x7fd4b8c00000 // | | | | // | | | free | // | | | | // | | | | size | capacity // | | | | // | | <- top -- + | 0x7fd4b88000a8 // | | | | // | | | used | // | | | | // | | | | // +--------------+ <- bottom --+ --+
看end()函数的实现,是在Metachunk的父类Metabase中定义的
class Metabase VALUE_OBJ_CLASS_SPEC { size_t _word_size; T* _next; T* _prev; protected:
size_t size() const volatile { return _word_size; } Metabase(size_t word_size) : _word_size(word_size), _next(NULL), _prev(NULL) {} public:
.... uintptr_t* end() const { return ((uintptr_t*) this) + size(); } ... };
那么这个end() 就是理解为Metabase的word_size=0x80000+ Metabase的地址 计算后得到 0x7fd4b8c00000
那么这个top就是Metachunk类中_top成员函数
接着进入红色函数
void SpaceManager::inc_used_metrics(size_t words) { // Add to the per SpaceManager total Atomic::add_ptr(words, &_allocated_blocks_words); // Add to the global total MetaspaceAux::inc_used(mdtype(), words); }
其中查看内存
// Sum of all space in allocated chunks size_t _allocated_blocks_words; //15个 这条就牛逼了 Atomic::add_ptr(words, &_allocated_blocks_words); //word=12 , (gdb) p this $25 = (SpaceManager * const) 0x7fd4c8050298 (gdb) p _allocated_blocks_words $26 = 15
进入分红函数
inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { intptr_t addend = add_value; bool mp = os::is_MP(); __asm__ __volatile__ (LOCK_IF_MP(%3) "xaddq %0,(%2)" : "=r" (addend) : "0" (addend), "r" (dest), "r" (mp) : "cc", "memory"); return addend + add_value; }
这个是内联汇编的打印汇编内容
//解释,这个是将12 加上 目标地址的值15,和为27,汇编指令为 (gdb) x/15i $pc => 0x7fd4ce975528 <Atomic::add_ptr(long, long volatile*)+32>: mov -0x8(%rbp),%rax //这个是参数1,为12 0x7fd4ce97552c <Atomic::add_ptr(long, long volatile*)+36>: mov -0x20(%rbp),%rdx //这个是参数2,为指针地址 0x7fd4ce975530 <Atomic::add_ptr(long, long volatile*)+40>: movzbl -0x9(%rbp),%ecx 0x7fd4ce975534 <Atomic::add_ptr(long, long volatile*)+44>: cmp $0x0,%cl 0x7fd4ce975537 <Atomic::add_ptr(long, long volatile*)+47>: je 0x7fd4ce97553a <Atomic::add_ptr(long, long volatile*)+50> 0x7fd4ce975539 <Atomic::add_ptr(long, long volatile*)+49>: lock xadd %rax,(%rdx) //交换叫加,等价于 xchg eax,(),那么$rax=15,(%rdx)=12,然后$rax=27 0x7fd4ce97553e <Atomic::add_ptr(long, long volatile*)+54>: mov %rax,-0x8(%rbp) 将27 存到指针地址,即为参数2的地址,将和存入了_allocated_blocks_words 0x7fd4ce975542 <Atomic::add_ptr(long, long volatile*)+58>: mov -0x18(%rbp),%rax 0x7fd4ce975546 <Atomic::add_ptr(long, long volatile*)+62>: mov -0x8(%rbp),%rdx 0x7fd4ce97554a <Atomic::add_ptr(long, long volatile*)+66>: add %rdx,%rax 0x7fd4ce97554d <Atomic::add_ptr(long, long volatile*)+69>: leaveq 0x7fd4ce97554e <Atomic::add_ptr(long, long volatile*)+70>: retq
查看内存情况
(gdb) p this $39 = (SpaceManager * const) 0x7fd4c8050298 (gdb) p * this $40 = (SpaceManager) {<CHeapObj<256u>> = {<AllocatedObj> = {_vptr.AllocatedObj = 0x7fd4cfa2c890 <vtable for SpaceManager+16>}, <No data fields>}, _lock = 0x7fd4c802e8f8, _mdtype = Metaspace::NonClassType, _chunks_in_use = {0x0, 0x0, 0x0, 0x7fd4b8800000}, _current_chunk = 0x7fd4b8800000, static _small_chunk_limit = 4, _allocated_blocks_words = 27, //将上边的汇编操作将15变成了17 _allocated_chunks_words = 524288, _allocated_chunks_count = 1, _block_freelists = {_dictionary = 0x0, static WasteMultiplier = 4}, static _expand_lock_name = 0x7fd4cf466138 "SpaceManager chunk allocation lock", static _expand_lock_rank = 3, static _expand_lock = 0x930758}
(gdb) p _vsm
$42 = (SpaceManager *) 0x7fd4c8050298,上面的就是这个_vsm
接着走流程 return result; 就是分配的top值 (gdb) p result $43 = (MetaWord *) 0x7fd4b88000a8
这个对象上边的黄色函数跳出的结果
接着走流程进入最早的橘色2
// Zero initialize. Copy::fill_to_aligned_words((HeapWord*)result, word_size, 0); copy.hpp static void fill_to_aligned_words(HeapWord* to, size_t count, juint value = 0) { assert_params_aligned(to); pd_fill_to_aligned_words(to, count, value); } //copy_x86.cpp static void pd_fill_to_aligned_words(HeapWord* tohw, size_t count, juint value) { pd_fill_to_words(tohw, count, value); } static void pd_fill_to_words(HeapWord* tohw, size_t count, juint value) { #ifdef AMD64 julong* to = (julong*) tohw; julong v = ((julong) value << 32) | value; while (count-- > 0) { *to++ = v; } #else juint* to = (juint*)tohw; count *= HeapWordSize / BytesPerInt; while (count-- > 0) { *to++ = value; } #endif // AMD64 }
打印内存结构
(gdb) p tohw $44 = (HeapWord *) 0x7fd4b88000a8 //以上是使用0 进行填充 (gdb) x/40x 0x7fd4b88000a8 0x7fd4b88000a8: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fd4b88000b8: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fd4b88000c8: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fd4b88000d8: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fd4b88000e8: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fd4b88000f8: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fd4b8800108: 0xf7f7f7f7 0xf7f7f7f7 0xf7f7f7f7 0xf7f7f7f7
至此就完成了 Array<u1>* 的12*8个字节的内存分配和初始化,即12个MetaWord