3.对象的建立过程解析

2.png
其中类加载机制以下:
image.png
对象建立过程解析:java

一、类加载检查

类在加载过程当中会首先判断该类是否已被加载,即,在方法区(元空间)上的常量池中去查找指向该类的指令,若是存在,再去判断该指令指向的类是否已经被加载、解析、初始化过,若是没有,就加载此类。

二、分配内存

当类被加载完以后,虚拟机就会给对象分配内存,此时对象的大小已经肯定,虚拟机会从堆(栈)的内存区域中划分出该对象大小空间的区域供存放该对象。

一、指针碰撞:

指针碰撞时jvm虚拟机默认的给对象分配内存的方式,即:把堆(或栈)上的一部份内存分红两部分,一部分依次放满了对象,此时对象在这部份内存上是整齐排放着,另外一部分是空白内存区域,等待放对象。两块区域的间隔点是用一个指针进行标记,若是在这块内存中又建立了对象,则指针会向后移动这个对象的大小的地址,供这个对象存放。
image.png算法

二、空闲列表:

当内存上存放的对象不是整齐规整存放的话,就会出现许多空白区域与对象交叉出现,此时就不能使用指针碰撞的方式去分配内存,空闲列表的方式就是维护一个能够存放对象的内存地址的集合列表,即记录哪些内存区域是能够存放对象的,当建立对象时,在列表中找一个空间合适的一块区域去存放,而后再更新列表。
image.png并发

在以上分配内存的过程当中,若是在给对象a分配内存的同时指针还没来得及修改,对象b同时也使用了原来的这个指针来分配内存。就会出现一块内存分配给了两个对象,即并发问题。

解决并发问题的方式:jvm

一、CAS

CAS即Compare and Swap,比较并交换算法,CAS有3个操做数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改成B,不然什么都不作。这里进行简述:利用cas方式解决建立对象的并发问题的逻辑是:对象在进行分配内存以前会将该线程指望的指针值与内存上的原有的指针值进行比较,若是相同,则先修改内存上的指针值,即向后移动该对象大小的空间,而后存放对象。若是不相同,则返回如今的指针值,而后重试以上操做。ui

二、本地线程分配缓冲(Thread Local Allocation Buffer,TLAB)

把将要存放对象的空白内存区域分红若干小块,每一个线程只容许在本身的那一小块的内存上进行分配对象内存区域。spa

三、初始化

即给对象赋默认值。若是不赋默认值,这个对象的该字段若是不set值的话,就没法get该字段的内容,程序会出错。若是赋默认值以后,就能够返回默认值。线程

四、设置对象头

对象由对象头(Header)、 实例数据(Instance Data)和对齐填充(Padding)三部分组成。

对象头:包含了该对象的必要信息,不只包括该对象的一些类元信息地址指针,还包含其余信息,好比对象的分代年龄,锁信息等。
实例数据:对象中各个实例字段的数据。
对齐填充:其中为了保持对象内存的整齐性,还包括了对齐指针来进行对对象的内存大小的填充。指针

五、执行init()方法

为对象赋用户本身的值,执行构造方法。code

对象头的类元信息解析

21.png
如上图所示:
对象在堆中建立,其对象头中存在指向该对象的类元信息的指针,也就是说,若是对象想要找到该对象的成员方法的具体方法内容(代码),就是经过这个对象头内的指针找的。对象

duixiang.add();

区分对象、类对象、类元信息:
类对象:类加载完成以后,是java虚拟机为方便用户操做该类的类元信息而建立的镜像对象,里面没有该类的信息,可是经过该类对象能够访问该类的信息。存放在堆中。

class<?extends Duixiang> duixiangClass = duixiang.getClass();

类元信息:存放类的相关信息,好比变量与成员方法,在方法区中。

对象头中的指针为压缩指针,做用是节省内存空间

未完待续~~~~

相关文章
相关标签/搜索