虛擬機遇到一條new指令時,首先將去檢查這個指令的參數是否能再常量池中定位到一個類的符號引用,并且檢查這個符號引用代表的類是否已經被加載、解析和初始化過。如果沒有,那必須先執行相應的類加載過程。在類加載檢查通過后,接下來虛擬機將為新生對象分配內存。對象所需內存的大小在類加載完成后便可完全確定,為對象分配空間的任務等同于把一塊確定大小的內存從Java堆中劃分出來。劃分方式:①指針碰撞(Bump the Pointer)。如果Java堆中的內存是絕對規整的,所有用過的內存都放在一邊,空閑的放在另一邊,中間放著一個指針作為分界點的指示器,那分配內存就僅僅是把那個指針向空閑那邊挪動一段與對象大小相等的距離,這種分配方式稱為“指針碰撞”。空閑列表(Free List):如果Java堆中的內存并不是規整的,已使用的內存和空閑的內存相互交錯,那就沒辦法簡單的進行指針碰撞了,虛擬機就必須維護一個列表,記錄上哪些內存塊是可用的,在分配的時候從列表中找到一塊足夠大的空間劃分給對象實例,并更新列表上的記錄。
選擇哪種分配方式由Java堆是否規整決定,而Java堆是否規整又有所采用的垃圾收集器是否帶有壓縮整理功能決定。分配內存方式:①是對分配內存空間的動作進行同步處理——實際上虛擬機采用CAS配上失敗重試的方式保證更新操作的原子性。②是把內存分配的動作按照線程劃分在不同的空間之中進行,即每個線程在Java堆中預先分配一小塊內存,稱為本地線程分配緩沖(Thread Local Allocation Buffer,TLAB)。哪個線程要分配內存,就在哪個線程的TLAB上分配,只有TLAB用完并分配新的TLAB時,才需要同步鎖定。