对象的内存布局

一、对象的创建过程

1、创建对象主要分一下几个步骤:

  • class loading
  • class linking(verification  preparation  resolution)
  • class innitializing
  • 申请对象内存
  • 成员变量赋默认值
  • 调用构造方法(1.成员变量赋初始值   2.执行构造方法语句)

2、解释一下上面的步骤:

第一步是将class文件load到内存中,第二步是linking,主要包括三小步:1.verification校验  2.preparation准备  给类的静态常量赋默认值  3.resolution做一个解析,第三步类初始化,将静态变量赋初始值的同时执行静态语句块。创建完对象之后需要向申请内存,成员变量赋默认值,然后调用构造方法在字节码层面,调用构造方法时将成员变量赋初始值,接下来调用构造方法语句super()调用父类。

二、对象的布局

作为对象的内存布局来讲主要分为两种:第一种叫普通对象 , 第二种叫做数组对象。

普通对象首先有:

      • 第一有对象头,在hotsport中叫做markword长度为8个字节
      • 第二个是ClassPointer 指针
      • 第三个是实例数据
      • 第四个是padding对齐,这个对齐是8的倍数

普通对象,首先有一个对象头markword 8个字节

三、对象头内具体都包括什么

对象头中的信息非常复杂,而且每一个版本的实现还不一样,而且markdown这个东西在不同的对象记录的东西也是不一样的,就以JDK8 Hotsport实现来说:

 markdown里面装的什么?    

第一是锁的信息 后三位分别是偏向锁的标志位、锁的标志位,代表对象有没有被锁定;第二是GC回收的次数以及分代年龄;第三是hashcode值;第四是线程id。

四、对象定位

对象的定位有两种:1、语柄池   2、直接指针

例如:T t = new T();  这里的t是如何找到他的对象,第一种方式是语柄池,通过间接指针,第一步把 t 指向两个指针 一个指向对象一个指向t.class。第二种是直接指,直接指向对象然后指向t.class      两种方式没有优劣之分,有的虚拟机用第一种有的用第二种;第一种需要先找到一个指针然后找下一个,第二种的效率比较高直接找到对象,两者在gc方面的效率方面第一种比较高,这里hotsport使用的是第二种。

五、对象如何分配

首先new一个对象的时候,先往栈上分配,栈上如果可以分配下就分配在栈上,然后栈上一弹出就没了,如果栈上分配不下,对象特别的大直接分配到堆内存,也就是老年代,如果对象不大,首先会进行线程本地分配,如果分配不下,会找到伊甸区然后进行GC过程,在GC的过程中年龄到了一定大小就会直接进入老年代,如果年龄没到,就会一次一次GC直到年龄到达为止;

以上就是对象的内存布局,如果有不足和有问题的地方,希望大家提出来,一起讨论一起进步!!!!!!

原文地址:https://www.cnblogs.com/dongl961230/p/13275011.html