Hotspot 内存管理之Universe 源码解析

     目录

1、定义

2、LatestMethodCache / NarrowPtrStruct

3、universe_init

4、universe2_init

5、universe_post_init

6、initialize_basic_type_mirrors

7、reserve_heap

8、oops_do


《Hotspot Java对象创建和TLAB源码解析》讲解Java对象创建和分配TLAB时,在《Hotspot 内存管理之MemoryService 源码解析》讲解MemoryService的set_universe_heap方法的调用时都频繁碰到Universe类,本篇博客就详细探讨Universe类的初始化和对外提供的接口。

1、定义

     Universe的定义位于hotspot src/shared/vm/memory/universe.hpp中,Universe类用来保存JVM中重要的系统类及其实例,如基础类型数组的Klass,用来提供对分配Java对象的CollectedHeap的访问入口,提供多种对象分配的方法。Universe定义的属性和对外提供的方法都是static的,除预先初始化好的重要的Klass或者oop外,关键的属性如下:

  •  LatestMethodCache* _finalizer_register_cache; //对应java_lang_ref_Finalizer类的register(Object finalizee)方法,该类是java_lang_ref包级私有的
  •  LatestMethodCache* _loader_addClass_cache;    //对应sun_reflect_DelegatingClassLoader类的addClass方法,DelegatingClassLoader是sun_reflect_ClassDefiner中定义的,包级访问,直接继承自java.lang.ClassLoader类
  •  LatestMethodCache* _pd_implies_cache;         //对应java_security_ProtectionDomain类的impliesCreateAccessControlContext方法
  •  LatestMethodCache* _throw_illegal_access_error_cache; //对应 Unsafe类的throwIllegalAccessError() 方法
  • CollectedHeap* _collectedHeap;  //负责Java对象分配的CollectedHeap引用
  • intptr_t _non_oop_bits; //用来标识某块内存不是一个合法的oop,在oop遍历时使用
  • NarrowPtrStruct _narrow_oop;//开启UseCompressedOops时,保存用来记录计算真实oop地址的base地址等属性
  • NarrowPtrStruct _narrow_klass; //开启UseCompressedClassPointers时,保存用来记录计算真实klass地址的base地址等属性
  • address _narrow_ptrs_base; //使用narrow_ptrs时的基地址
  • int  _base_vtable_size; //Klass中虚函数表占用内存的最小值,实际就是Object类Klass的虚函数表的大小
  • size_t _heap_capacity_at_last_gc; //上一次GC时的堆内存的容量
  • size_t _heap_used_at_last_gc;  //上一次GC时的堆内存的已使用的内存量

  Universe定义的方法大部分是读写属性的相关方法,重点关注Universe的初始化和下列方法的实现即可。因为Universe没有定义实例属性,都是静态属性和静态方法,所以Universe没有定义构造方法,初始化时也不需要new一个Universe,而是通过三个友元方法完成Universe的各静态属性的初始化,这三个友元方法的定义如下:

这三个方法都是在JVM启动时在init_globals()方法中依次调用的。 

2、LatestMethodCache / NarrowPtrStruct

   LatestMethodCache用来缓存Method*,调用方通过get_method方法获取的永远是该方法的最新版本,LatestMethodCache内部屏蔽了类重定义(Class Redefinition)时方法实现发生变更的问题。LatestMethodCache定义的属性如下:

_klass就是该方法所属的类的Klass,_method_idnum是该方法在Klass中的方法ID,实际是该方法在Klass方法数组中的序号,当类重定义时该方法对应的Method*可能发生改变,_method_idnum可能以为增加了新的方法也发生改变,但是_method_idnum会保证永远对应着原来的那个方法,从保证get_method方法返回的用于是该方法的最新版本。get_method方法的实现如下图:

 LatestMethodCache的init方法的实现如下图:

   NarrowPtrStruct是一个结构体,用来保存开启指针压缩时计算压缩指针真实地址的base地址等属性信息,其定义如下图:

base和shift属性的用法可以参考用于计算压缩指针真实地址oopDesc::decode_heap_oop_not_null方法的实现,如下图:

3、universe_init

     universe_init方法的执行依赖于codeCache_init 和stubRoutines_init 方法的成功执行,是最新被调用的universe初始化方法,主要用来初始化collectedHeap,Metaspace和TLAB等组件,其源码实现如下:

jint universe_init() {
  assert(!Universe::_fully_initialized, "called after initialize_vtables");
  //校验参数的合法
  guarantee(1 << LogHeapWordSize == sizeof(HeapWord),
         "LogHeapWordSize is incorrect.");
  //sizeof(oop)和sizeof(HeapWord)实际都是一个指针的大小
  guarantee(sizeof(oop) >= sizeof(HeapWord), "HeapWord larger than oop?");
  guarantee(sizeof(oop) % sizeof(HeapWord) == 0,
            "oop size is not not a multiple of HeapWord size");
  TraceTime timer("Genesis", TraceStartupTime);
  //计算部分重要的系统类的关键属性在oop中的偏移量,方便快速根据内存偏移读取属性值
  JavaClasses::compute_hard_coded_offsets();
  //初始化collectedHeap和TLABA
  jint status = Universe::initialize_heap();
  if (status != JNI_OK) {
    return status;
  }
  //初始化负责元空间内存管理的Metaspace
  Metaspace::global_initialize();

  // 初始化ClassLoaderData的_the_null_class_loader_data属性
  ClassLoaderData::init_null_class_loader_data();

  // 初始化属性
  Universe::_finalizer_register_cache = new LatestMethodCache();
  Universe::_loader_addClass_cache    = new LatestMethodCache();
  Universe::_pd_implies_cache         = new LatestMethodCache();
  Universe::_throw_illegal_access_error_cache = new LatestMethodCache();

  //UseSharedSpaces默认为true,表示为元数据使用共享空间
  if (UseSharedSpaces) {
    //初始化共享空间
    MetaspaceShared::initialize_shared_spaces();
    StringTable::create_table();
  } else {
    //不使用共享空间时,分别初始化各个组件,SymbolTable表示符号表,StringTable表示字符串表
    SymbolTable::create_table();
    StringTable::create_table();
    ClassLoader::create_package_info_table();

    if (DumpSharedSpaces) {
      MetaspaceShared::prepare_for_dumping();
    }
  }
  if (strlen(VerifySubSet) > 0) {
    Universe::initialize_verify_flags();
  }

  return JNI_OK;
}

jint Universe::initialize_heap() {
  //如果使用ParallelGC
  if (UseParallelGC) {

    Universe::_collectedHeap = new ParallelScavengeHeap();
  } else if (UseG1GC) {
    //如果使用G1GC
    G1CollectorPolicyExt* g1p = new G1CollectorPolicyExt();
    g1p->initialize_all();
    G1CollectedHeap* g1h = new G1CollectedHeap(g1p);
    Universe::_collectedHeap = g1h;

  } else {
    //如果使用分代回收
    GenCollectorPolicy *gc_policy;
    //不同的回收策略
    if (UseSerialGC) {
      gc_policy = new MarkSweepPolicy();
    } else if (UseConcMarkSweepGC) {
      if (UseAdaptiveSizePolicy) {
        gc_policy = new ASConcurrentMarkSweepPolicy();
      } else {
        gc_policy = new ConcurrentMarkSweepPolicy();
      }
    } else { // default old generation
      gc_policy = new MarkSweepPolicy();
    }
    gc_policy->initialize_all();

    Universe::_collectedHeap = new GenCollectedHeap(gc_policy);
  }
  //设置TLAB的最大值
  ThreadLocalAllocBuffer::set_max_size(Universe::heap()->max_tlab_size());
  //初始化collectedHeap
  jint status = Universe::heap()->initialize();
  if (status != JNI_OK) {
    return status;
  }

#ifdef _LP64
  if (UseCompressedOops) {
     //根据不同的堆内存大小设置narrow_oop_s
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值