(二)jvm對象的創建和訪問

一 對象的創建

虛擬機首先會檢查是否能在常量池中定位一個類的符號引用,檢查這個符號引用是否已經被加載解析和初始化。

類加載檢查通過後,會爲新生對象分配內存,對象所需內存的大小在類加載完成後就已經確定。

在虛擬機中爲對象分配內存的方式有兩種:指針碰撞和空閒列表

指針碰撞

    java堆中的內存是規整的,即已經使用的內存在一邊,空閒的內存在另外一邊,中間放着一個指針作爲分界點的指示器,每次爲對象分配內存的時候指針就會往空閒內存的一邊移動一段與待分配對象內存大小相同的距離

空閒列表

   java內存不是規整的,已經使用內存和未使用內存相互交錯,虛擬機必須維護一個表,記錄哪些內存塊是可以使用的,在分配的時候從表中找到一塊足夠大的空間劃分給對象,並更新表上的記錄。

使用哪種分配方式取決於java堆是否規整,而java堆是否規整取決於垃圾收集器是否帶有壓縮整理功能

併發情況下,虛擬機創建對象也不是線程安全的,通過以下兩種方式解決

1,對分配內存空間的動作進行同步處理

2每個線程預先在java堆中分配一小塊內存,即本地線程分配緩衝(TLAB),那個線程需要分配內存就在TLAB上面分配,當使用完TLAB需要新的TLAB時纔會進行同步鎖定,通過-XX:/-UseTLAB參數來設定


對象的內存佈局

對象在內存存儲的佈局可以分爲三個部分:對象頭,實例數據,對齊填充

對象頭包括兩個部分

一實用來存儲對象自身的運行時數據,如哈希嗎,GC分代年齡,鎖狀態標誌,線程持有的鎖,偏向線程ID,偏向時間戳

二類型指針,即對象指向他的類元數據的指針,虛擬機通過這個指針來確定這個對象是哪個類的實例

如果是普通java對象,可以通過java對象的元數據信息來確定java對象的大小,如果是數組對象,則必須有一塊專門存放數組長度的數據。

實例數據:是對象真正存儲的有效信息

對齊填充:並不是一定需要,無特殊含義,僅僅起着佔位符的作用,JVM自動內存管理系統要求對象大小必須是8字節的整數倍,當對象實例數據沒有對齊時,就要通過對齊填充來補全。

訪問對象的方式有兩種:句柄訪問和直接指針訪問

句柄訪問:在java堆中劃分一塊內存作爲句柄池,reference中存儲的就是對象的句柄地址,而句柄對象中包含了對象實例數據和對象類型數據的具體地址,特點是穩定

直接指針訪問:直接存儲的是對象地址,在java堆對象中存放類型數據的指針,較句柄訪問來說,省去了一次指針定位,特點是速度快。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章