zoukankan      html  css  js  c++  java
  • 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 '00', __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

    
    
    
  • 相关阅读:
    0045算法笔记——【随机化算法】舍伍德随机化思想搜索有序表
    精进~如何成为很厉害的人
    哪些小习惯一旦养成终生受用?
    2016第24周四
    2016第24周三
    2016第24周二
    2016第24周一
    2016第23周日
    前端资源汇总
    2016第23周五
  • 原文地址:https://www.cnblogs.com/zytcomeon/p/14583352.html
Copyright © 2011-2022 走看看