JVM高級特性-二、JVM在堆中對象的分配、布局、訪問過程


  前面介紹了jvm運行時數據區域后,下面講解下對內存中數據的其他細節,看他們是如何創建、布局及訪問的

  一、對象的創建

 

   1.對象的分配

 

   對象的創建分配方式主要有兩種:指針碰撞和空閑列表

 

   指針碰撞:  

     假設堆內存中是絕對規整的,那么,在為新對象分配內存空間時,只需要將指針向空閑空間方向移動新對象

   所需大小的一段出來即可。

 

     一般使用帶有compact(整理)過程的收集器時,使用指針碰撞

 

   空閑列表

     如果內存不是規整的,這時就需要維護一個列表,記錄哪些內存是空閑的,在分配空間時,從列表中找出一塊

   足夠大的空間划分為對象實例並更新列表記錄

 

   使用基於mark-sweep算法的收集器時,使用空閑列表

 

   2.對象的初始化及設置

      初始化:內存分配完成后就是對對象進行初始化,虛擬機將初始化的內存空間都初始化為0值,

      這就是為什么對象的實例字段在java代碼中不需要初始化也可以使用

      設置:之后,虛擬機對對象進行一些必要設置,主要是往對象頭中存入類的元數據信息、對象的哈希值、分代年齡等。

      init: 經過上面兩步后對象創建完成,但所有字段還都是0值。最后就是執行init方法,按程序員的意思初始化對象

      完成上述三步后,一個對象就算創建完成。

 

   二、對象的內存布局

     對象在內存中存儲的布局主要分為三部分,對象頭、實例數據、對齊填充

     對象頭

       對象頭在對象設置階段提到過,即在設置階段會向對象頭中存入一些類的元數據信息、哈希值、分代年齡等

       對象中主要分為兩部分:運行時數據和類型指針

         運行時數據:主要存儲上面對象設置階段存儲的哈希碼、分代信息、鎖狀態標識、線程持有的鎖等。

         類型指針:主要存儲對象的類元數據的指針,即這個對象是哪個類的實例,此外,如果對象類型是數組,

         對象頭中還會存儲一個代表數據長度的數據

         對齊填充:不是必然存在的,在Hotspot中,要求對象起始地址必須是8字節的倍數,

         當對象實例部分沒對齊時,用對齊填充來補全。

   三、對象的訪問定位

     java程序是通過棧上的reference數據來操作對象實例的,因此它只是一個引用,具體定位方式jvm有不同實現

     主流實現方式有兩種:使用句柄和直接指針

      

     句柄池:

       原理:java堆中會划出一片區域作為句柄池,reference存儲的就是句柄地址,

          里面包含對象實例數據的指針和對象類型指針

 

       好處:如果對象被移動,只需改變句柄池中存儲的地址

     直接指針

       原理:如果使用的是直接指針,那么reference中存儲的就是對象的地址

       好處:省去了一次定位的時間,效率更高

 

     Hotspot使用的是直接指針方式

      

          

          

 

    

        

    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM