1. 程式人生 > >九、內存分配原理

九、內存分配原理

避免 http 圖片 一個 回收 完全 接口類 寄存器 以及

盡管Java對象的內存分配可以選擇在堆外進行,但是不可否認這僅僅只是為了降低GC回收頻率以及提升GC回收效率的一種輔助手段,所以Java堆仍然是分配/存儲對象實例的主要區域。JVM中包含三種引用類型:

1、類類型;

2、數組類型;

3、接口類型;

這些引用類型的值分別由類實例、數組實例、和接口的派生類實例負責動態創建。如果是在語法層面上,創建一個對象實例無非就是使用new關鍵字即可。

簡單來說,當語法層面使用new關鍵字創建一個Java對象的時候,JVM首先會檢查這個new指定的參數是否在常量池中定位到一個類的符號引用,然後檢查與這個符號引用對應的類是否已經成功經歷過加載、解析、初始化。完成裝載步驟以後,就已經完全可以確定創建對象實例所需要的內存空間大小了。JVM會為其進行內存分配,以存儲生成的對象實例。

技術分享圖片

基於線程安全考慮,如果一個類在分配內存前已經成功完成類裝載,那麽JVM會優先選擇在thread local allocation中為對象實例分配內存空間。TLAB在Java堆區中是一塊線程私有區域,它包含在Eden控件中,除了可以避免一系列的非線程安全問題外,同時還能夠提升內存分配的吞吐量,因此我們可以將這種內存分配方式稱之為快速分配策略。不過TLAB的空間是很小的,僅是Eden空間的1%。一旦分配失敗,則在Eden空間中分配。如果Eden也無法分配,那麽就會進行GC,直到可以分配為止。(如果是大對象,則直接在老年代分配);

當前對象成功分配內存以後,就會初始化對象。JVM首先會進行零值初始化,確保了對象實例字段可以不用賦值就可以使用。

零值初始化以後,JVM就會初始化對象頭和實例數據。

最後,將對象的引用入棧,再更新PC寄存器中的字節碼指令地址。

經過以上一系列步驟以後,Java對象才算是真的創建成功。

九、內存分配原理