基於HotSpot算法
基本類型對象的建立併發
1 當虛擬機遇到一條new指令時,嘗試在常量池中定位到相關類的符號引用佈局
2 檢查這個符號引用表明的類是否已經加載,解析,初始化,若是沒有先執行類加載spa
3 完成2後可肯定對象所需的內存大小操作系統
4 從堆中劃分出相應大小的內存。線程
5 初始化對象:對象的哈希碼,gc分代年齡,對應類的信息。3d
6 根據代碼設置對象初始值。指針
問題一:對象
步驟3是如何肯定對象所需內存的大小的?blog
首先看一下對象在內存中的存儲佈局:
hotspot規定對象的起始地址必須是8字節的整倍數,即對象的大小必須是8字節的整數倍。對象頭通常格式較固定,能夠保證這一點,當實例數據不知足的時候,須要對齊填充部分來一塊兒保證。
問題二:
步驟4中是如何從堆中劃份內存的?
堆中劃份內存有兩種方法:指針 和 空閒列表。使用哪一種方式取決於堆是不是規整的(堆是否能規整取決於使用的垃圾回收算法)。
規整的意思是說堆中使用過的內存和空閒內存有明顯的劃分界線,而不是混在一塊兒的。
若是是規整的,那麼就可使用指針法,在使用過的內存和空閒內存的分界點用一個指針表示,分配內存時只要將指針向空閒內存方向移動一段與對象內存大小相等的距離。
若是不是規整的,那隻能使用空閒列表,空閒列表是指虛擬機維護一個列表,記錄哪些內存塊是使用過的哪些是空閒的,分配內存時從列表中選擇一塊知足對象大小的內存塊。這裏如何選擇內存塊,估計就是學生時代學的操做系統講的那些內容了,如何保證內存碎片較少之類的(後續整理)
hotspot使用的應該是指針
分配內存的時候還涉及到併發的問題,兩種解決方式:
1 對分配內存這種操做進行同步處理,CAS保證操做的原子性
2 本地線程分配緩衝TLAB,預先爲每一個線程分配一小塊內存TLAB,須要內存時各線程先在本身的TLAB上分配,當TLAB不夠用的時候纔會須要同步。
CAS:
簡單描述下,大致採用的是樂觀鎖的思想,不使用鎖,多個線程去改同一個變量時,均可以嘗試去改,只會有一個線程成功,失敗的線程也會馬上獲得反饋,不會阻塞。
CAS中有三個變量,內存中的值V,預期原值A,新值B,每一個線程嘗試去改變量的時候,先判斷A和V是否相等,若是相同,則將B更新到內存,不然更新失敗。