jvm中對象是怎麼存儲的,對象的內存佈局是怎樣的

對象通過new,反射,clone等方式創建完畢後被存儲到堆中,那麼對象是以什麼樣的方式存儲在堆中的?

對象的內存佈局

對象在堆內存的內存佈局主要有三部分,即對象頭,實例數據,對其填充

對象頭

對象頭主要包含兩部分的內容,一個叫運行時元數據(mark word),一個叫類型指針

  • 1.運行時元數據
    • 哈希值(hashcode):對象在堆空間中都有一個首地址值,棧空間的引用根據這個地址指向堆中的對象,這就是哈希值起的作用
    • GC分代年齡:對象首先是在Eden中創建的,在經過多次GC後,如果沒有被進行回收,就會在survivor中來回移動,其對應的年齡計數器會發生變化,達到閾值後會進入養老區
    • 鎖狀態標誌,在同步中判斷該對象是否是鎖
    • 線程持有的鎖
    • 線程偏向ID
    • 偏向時間戳
  • 2.類型指針,指向元數據區的代表當前類的class對象,確定該對象所屬的類型

說明:如果對象是數組,則還需要記錄數組的長度

實例數據(Instance Data)

它是對象真正存儲的有效信息,包括程序代碼中定義的各種字段類型(包括從父類繼承下來的和自己本身擁有的字段),注意這裏有一些規則:相同寬度的字段總是被分配在一起,父類中定義的變量會出現在子類之前,因爲父類的加載是優先於子類加載的

對齊填充

沒有特殊含義,僅僅起到佔位符的作用

小結

現在有一個Customer cust = new Custome()的對象,通過上面的敘述,我們通過一張圖來直觀的瞭解下:

在這裏插入圖片描述

補充:對象訪問方式

在創建好對象後,通過棧幀上的引用訪問堆中的實例,這種訪問方式可以分爲兩種方式:句柄訪問和直接指針(HotSpot採用)

句柄訪問:

在這裏插入圖片描述

直接指針:

和我們介紹內存佈局是一樣的
在這裏插入圖片描述
兩種方式比較:
直接指針效率往往比句柄訪問高,且不需要專門維護句柄池,內存花費小,當對象實例發生移動時,通過指針訪問的引用也要發生變化,而句柄方式的reference則不需要改變

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