源码分析:Java对象的内存分配(2)

if (UseBiasedLocking) {
                result->set_mark(ik->prototype_header());
              } else {
                result->set_mark(markOopDesc::prototype());
              }
              result->set_klass_gap(0);
              result->set_klass(k_entry);

  7.把对象地址引入栈,并继续执行下一个字节码

SET_STACK_OBJECT(result, 0);
              UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1);

  8.若该类型没有被解析,就会调用InterpreterRuntime的_new函数完成慢速分配

// Slow case allocation
        CALL_VM(InterpreterRuntime::_new(THREAD, METHOD->constants(), index),
                handle_exception);
        SET_STACK_OBJECT(THREAD->vm_result(), 0);
        THREAD->set_vm_result(NULL);
        UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1);

以上就是快速分配的过程,其流程图如下,关键在于快速分配在Eden区所使用的无锁指针碰撞技术

 二、慢速分配

  接下来看看慢速分配是如何进行的:
  1.InterpreterRuntime的_new函数定义在/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp中:

IRT_ENTRY(void, InterpreterRuntime::_new(JavaThread* thread, constantPoolOopDesc* pool, int index))
  klassOop k_oop = pool->klass_at(index, CHECK);
  instanceKlassHandle klass (THREAD, k_oop);

// Make sure we are not instantiating an abstract klass
  klass->check_valid_for_instantiation(true, CHECK);

// Make sure klass is initialized
  klass->initialize(CHECK);

oop obj = klass->allocate_instance(CHECK);
  thread->set_vm_result(obj);
IRT_END

  该函数在进行了对象类的检查(确保不是抽象类)和对该类型进行初始化后,调用instanceKlassHandle的allocate_instance进行内存分配。
  其中instanceKlassHandle类由DEF_KLASS_HANDLE宏进行声明,注意该类重载了成员访问运算符”->”,这里的一系列成员方法的访问实际上是instanceKlass对象的访问。

type*    operator -> () const      { return (type*)obj()->klass_part(); }

  2.所以实际上是调用了instanceKlass的allocate_instance()成员函数:
  allocate_instance()定义在/hotspot/src/share/vm/oops/instanceKlass.cpp
  (1).检查是否设置了Finalizer函数,获取对象所需空间的大小

instanceOop instanceKlass::allocate_instance(TRAPS) {
    bool has_finalizer_flag = has_finalizer(); // Query before possible GC
    int size = size_helper();  // Query before forming handle.

  (2).调用CollectedHeap的obj_allocate()创建一个instanceOop(堆上的对象实例),并根据情况注册Finalizer函数

    KlassHandle h_k(THREAD, as_klassOop());

instanceOop i;

i = (instanceOop)CollectedHeap::obj_allocate(h_k, size, CHECK_NULL);
      if (has_finalizer_flag && !RegisterFinalizersAtInit) {
        i = register_finalizer(i, CHECK_NULL);
      }
      return i;

  3.CollectedHeap::ojb_allocate()定义在/hotspot/src/share/vm/gc_interface/CollectedHeap.hpp中,它将转而调用内联函数obj_allocate()

  4.obj_allocate()定义在/hotspot/src/share/vm/gc_interface/CollectedHeap.inline.h中,若当正处于gc状态时,不允许进行内存分配申请,否则将调用common_mem_allocate_init()进行内存分配并返回获得内存的起始地址,随后将调用post_allocation_setup_obj()进行一些初始化工作 

oop CollectedHeap::obj_allocate(KlassHandle klass, int size, TRAPS) {
 //...assert
  HeapWord* obj = common_mem_allocate_init(size, false, CHECK_NULL);
  post_allocation_setup_obj(klass, obj, size);
  NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
  return (oop)obj;
}

  5.common_mem_allocate_init()分为两部分,将分别调用common_mem_allocate_noinit()进行内存空间的分配和调用init_obj()进行对象空间的初始化

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/d99615c53ee9166c69daae92f15e67af.html