设为首页 加入收藏

TOP

源码分析:Java对象的内存分配(三)
2015-12-01 14:11:47 来源: 作者: 【 】 浏览:24
Tags:源码 分析 Java 对象 内存 分配
pace");


? ? if (JvmtiExport::should_post_resource_exhausted()) {
? ? ? JvmtiExport::post_resource_exhausted(
? ? ? ? JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP,
? ? ? ? "Java heap space");
? ? }


? ? THROW_OOP_0(Universe::out_of_memory_error_java_heap());


  7.对象内存分配后的初始化过程包括两部分,一个是init_obj()完成对对象内存空间的对齐和填充,一个是post_allocation_setup_obj()对堆上的oop对象进行初始化。


  (1).init_obj():


void CollectedHeap::init_obj(HeapWord* obj, size_t size) {
? assert(obj != NULL, "cannot initialize NULL object");
? const size_t hs = oopDesc::header_size();
? assert(size >= hs, "unexpected object size");
? ((oop)obj)->set_klass_gap(0);
? Copy::fill_to_aligned_words(obj + hs, size - hs);
}


  hs就是对象头的大小,fill_to_aligned_words将对象空间除去对象头的部分做填0处理,该函数定义在/hotspot/src/share/vm/utilities/copy.h中,并转而调用pd_fill_to_aligned_words()。
  pd_fill_to_aligned_words根据不同平台实现,以x86平台为例,该函数定义在/hotspot/src/cpu/x86/vm/copy_x86.h中:


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
}


  该函数的作用就是先将地址类型转换,然后把堆的字数转化为字节数,再对该段内存进行填值(value = 0)处理


  (2).post_allocation_setup_obj()调用了post_allocation_setup_common()进行初始化工作,然后调用post_allocation_notify()通知JVMTI和dtrace
  


void CollectedHeap::post_allocation_setup_obj(KlassHandle klass,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? HeapWord* obj,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? size_t size) {
? post_allocation_setup_common(klass, obj, size);
? assert(Universe::is_bootstrapping() ||
? ? ? ? !((oop)obj)->blueprint()->oop_is_array(), "must not be an array");
? // notify jvmti and dtrace
? post_allocation_notify(klass, (oop)obj);
}


  post_allocation_setup_common()如下:


void CollectedHeap::post_allocation_setup_common(KlassHandle klass,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? HeapWord* obj,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? size_t size) {
? post_allocation_setup_no_klass_install(klass, obj, size);
? post_allocation_install_obj_klass(klass, oop(obj), (int) size);
}


  post_allocation_setup_no_klass_install()根据是否使用偏向锁,设置对象头信息等,即初始化oop的_mark字段。post_allocation_install_obj_klass()设置对象实例的klassOop引用,即初始化oop的_metadata(_klass/_compressed_klass)字段 。


  以上内容就是堆实现无关的慢速分配过程,其流程图如下:



首页 上一页 1 2 3 下一页 尾页 3/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇数据库Blob数据类型转String 下一篇Java常量池解析与字符串intern简介

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: