java JVM 對象與內存

對象的創建

一 判斷是否需要類加載

虛擬機遇到new 指令時,先去常量池中檢查有沒有這個類的符號引用,並且檢查這個符號引用代表的類是否已被加載,解析和初始化過。如果沒有,必須先執行類加載過程

二 對象內存的分配

在確定了對象的空間大小之後,爲對象分配空間的任務等同於把一塊確定大小的內存從Java堆中劃分出來。
分配的方法有兩種,取決於Java堆所採用的垃圾收集器是否帶有壓縮整理。
如果用Serial,ParNew等等帶Compact壓縮過程的收集器時,就要用指針碰撞分配算法,如果用Mark-Sweep算法的收集器時,通常採用空閒列表法。

指針碰撞:

Java堆由於壓縮收集算法變得絕對規整,所有用過的內存都放一邊,空閒的內存放另一邊,中間放着一個指針作爲分界點的指示器,那所分配的內存就是把那個指針往空閒的空間挪動了一段與對象大小相等的距離。

空閒列表:

Java堆內存不是規整的,已使用的內存和未使用的內存錯綜複雜,虛擬機必須維護一個列表,記錄哪些內存塊是可用的,哪些是不可用的,在分配時從列表中找到足夠大的一塊空間劃分給對象實例,並更新列表。

對象創建劃分操作的線程安全性

對象在虛擬機中創建是非常頻繁的行爲,即使是僅僅修改一個指針的位置,在併發的情況下也並不是線程安全的,可能給對象A分配內存還沒分完,對象B也使用原來的指針來分配內存。解決這種併發的線程安全問題有兩種方案

一、CAS操作:

對分配內存的動作進行同步處理,用CAS配上失敗重試的方式保證更新操作的原子性

二、TLAB:

把內存分配的動作按照線程劃分在不同的空間中進行,每個線程在JAVA堆中預先分配一小塊內存,稱爲本地線程分配緩衝(Thread Local Allocation Buffer,TLAB)。哪個線程要分配內存,就在哪個線程的TLAB上分配,只有TLAB用完該分配新的TLAB時,才需要同步鎖定。是否需要用TLAB。通過-XX:+/-UseTLAB參數來設定。

收尾:

內存分配完成後,虛擬機要將分配到的內存空間初始化爲0值(不包括對象頭),使用TLAB的話這一工作可以提前至TLAB分配時進行。這易操作使對象的實例字段在Java代碼中不賦初值就可以使用。
之後虛擬機對對象的對象頭進行設置
這時所有對象的初值都是空值,對象的產生纔剛剛開始,之後會執行init(初始化)方法,將對象按照程序員的意願進行初始化,這樣一個真正可用的對象纔算是完全產生出來,

對象的內存佈局

對象在內存中的佈局分爲三塊區域:對象頭(Header),實例數據和對齊填充。

對象頭

對象頭又分爲兩大部分:MarkWord 和類型指針

MarkWord:

在這裏插入圖片描述
對象頭信息是與對象自身定義的數據無關的額外存儲成本,所以MarkWord被設計成非固定的數據結構以便在極小的空間裏存儲耿肯多的信息,他會根據對象的狀態複用自己的存儲空間,
對象在未鎖定的情況下:
25bit :對象的hash碼;
4 bit : 對象的分代年齡
2 bit : 鎖的標誌位
1 bit : 0

類型指針:

對象指向她的類元數據的指針,虛擬機藉助這個指針來確定這個對象屬於哪個類的實例,看一個類的元數據信息不一定要經過對象本身

如果是數組的話,對象頭中還必須有一塊用於記錄數組長度的數據,因爲虛擬機可以從對象的元數據那裏確定對象的大小,但從數組的元數據那裏獲取不到數組的大小。

實例部分:

父類繼承的和自己的字段內容都需記錄下來
Java虛擬機中有默認的分配策略,一般相同寬度的字段總是被分在一起,在父類中定義的變量會出現在子類的之前。如果CompactField參數爲true (默認)子類中較窄的變量也可能會插入到父類變量的空隙之中。

對齊填充:

HotSpot 規定對象的起始地址必須是8字節的整數倍,沒有對齊時要用這部分對齊填充。


對象的訪問定位

Java程序需要通過棧上的reference數據來操作堆上的具體對象。
這個reference引用通過何種方式去定位對象的位置,有兩種,使用句柄和直接指針

使用句柄:

Java堆中會劃出一塊內存作爲句柄池,reference中存儲的就是對象的句柄地址,而句柄中包含了對象的實例數據與類型數據各自的具體地址。
在這裏插入圖片描述

直接指針

reference中存儲就是在堆中分配的對象實例數據的地址;

而對象實例數據中需要有這個對象類型數據的相關信息(前面文章討論了HotSpot使用對象頭來存儲對象類型數據地址);
在這裏插入圖片描述
這兩種對象訪問各有優勢,使用句柄1訪問的最大好處就是reference中存儲的是穩定的句柄地址,在對象被移動(垃圾收集移動對象)時只會改變句柄中的實例數據指針,而reference本身不需要修改。
使用直接指針訪問的最大好處就是速度快。
Sun HotSpot而言,他是使用第二種方式進行對象訪問的。

發佈了124 篇原創文章 · 獲贊 9 · 訪問量 2474
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章