建立一個對象一般是須要new關鍵字,安全
- 當虛擬機遇到一條new指令時,
- 首先檢查這個指令的參數是否在常量池中定位到一個類的符號引用,
- 而且檢查這個符號引用表明的類是否已被加載、解析和初始化過。
- 若是是
- 類加載檢查經過後,
- 虛擬機將爲新生對象分配內存。
- 爲對象分配空間的任務等同於把一塊肯定大小的內存從Java堆中劃分出來。
分配的方式有兩種:線程
- 一種叫 指針碰撞 ,
- 假設Java堆中內存是絕對規整的,
- 用過的和空閒的內存各在一邊,
- 中間放着一個指針做爲分界點的指示器,
- 分配內存就是把那個指針向空閒空間的那邊挪動一段與對象大小相等的距離。
- 另外一種叫 空閒列表 :
- 若是Java堆中的內存不是規整的,
- 虛擬機就須要維護一個列表,
- 在分配的時候從列表中找到一塊足夠大的空間劃分給對象實例,並更新列表上的記錄。
- 採用哪一種分配方式是由*Java堆是否規整決定的,
- 而Java堆是否規整是由所採用的垃圾收集器是否帶有壓縮整理功能決定的。
須要考慮的問題就是對象建立時的線程安全問題,指針
- 有兩種解決方案:
- 一是對分配內存空間的動做進行同步處理;
- 另外一種是吧內存分配的動做按照線程劃分在不 同的空間之中進行,
- 即每一個線程在Java堆中預先分配一小塊內存(TLAB),
- 哪一個線程要分配內存就在哪一個線程的TLAB上分配,
- 只有TLAB用完並分配 新的TLAB時才須要同步鎖定。
內存分配完成後,虛擬機須要將分配到的內存空間初始化爲零值。對象
- 這一步操做保證了對象的實例字段在Java代碼中能夠不賦初始值就能夠直接使用。