在類加載檢查通過後,Java虛擬機將爲對象分配內存。對象所需的內存空間在類加載完後便可以完全確定。
分配內存有兩種方法:
(1)指針碰撞
如果Java堆中的內存是規整的,佔用的內存放一邊,空閒的內存在另一邊,則分配內存就是將分界點指針向空閒內存移動與對象大小相同的距離。
如果Java堆中的內存不是規整的,那麼虛擬機就要維護一個列表,記錄哪些內存塊是可用的,在分配的時候從列表中找到一塊足夠大的空間劃分給對象實例,並更新列表上的記錄。
分配內存的操作不是線程安全的。如何保證線程安全?
(1)對分配內存的操作進行同步處理,採用CAS加上失敗重試的方法保證原子性。
(2)將分配內存的操作在線程各自的空間中進行。每個線程在Java堆中預先分配一小塊內存,稱爲本地線程分配緩衝(TLAB),哪個線程要分配內存,就在哪個線程的TLAB上分配。只有TLAB用完並分配新的TLAB時,才需要同步鎖定。
虛擬機將分配到的內存都初始化爲零值。接着設置對象頭信息,例如對象是哪個類的實例、對象的哈希碼、對象的GC分代年齡等信息。