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();

類元信息:存放類的相關信息,好比變量與成員方法,在方法區中。

對象頭中的指針爲壓縮指針,做用是節省內存空間

未完待續~~~~

相關文章
相關標籤/搜索