您好,登錄后才能下訂單哦!
這篇文章主要講解了“Java對象存儲內存布局的方法是什么”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Java對象存儲內存布局的方法是什么”吧!
眾所周知,Java是一門面向對象的語言,那么一個對象在內存中都包含什么東西呢,首先,對象大部分是存儲在堆上的(逃逸除外 )。
那么對象存儲在堆中主要分為三個部分
對象頭、對象實例數據、對齊補充(數組會多一個數組長度)
對象頭:
mark word: 存儲對象的hashCode、鎖信息(鎖升級)或分代年齡或GC標志等信息
類型指針: 存儲指向對象所屬類(元數據中class文件)的指針,JVM通過這個確定這個對象屬于哪個類
對象實例數據:
new出的對象信息,存放類的屬性數據信息,包括父類的屬性信息;
對齊補充
數組對象會多對齊填充
JVM要求對象占用的空間必須是8 的倍數,方便內存分配(以字節為最小單位分配),因此這部分就是用于填滿不夠的空間湊數用的。
主流的訪問方式主要有句柄與直接指針
句柄:
Java堆中劃分出一塊內存作為句柄池,棧中的reference中存儲的事對象的句柄地址,而句柄中包含了對象實例數據與類型數據各自具體的地址信息
直接指針:
java堆中對象的內存布局必須考慮如何防止訪問類型數據的相關信息,reference中存儲的直接是對象地址。
直接指針訪問對象不需要多一次間接訪問開銷,而句柄方便在對象地址發生改變時(垃圾回收會移動對象地址)只需要改變句柄中的指針引用本身不需要改變。
虛擬機遇到new指令時,先去檢查指定的類是否被加載、驗證、準備(為類中的所有靜態變量分配內存空間,并為其設置一個初始值 ) 、解析、初始化過。
類檢查后虛擬機為新對象分配內存
如何保證并發情況分配堆內存安全
虛擬機采用CAS配上失敗重試保證原子性
把內存分配交給線程,在創建線程時分配空間,把分配內存的任務交給線程支配。通過TLAB(Thread local Allocation Buffer)開啟
分配完內存后設置對象頭,如哪個類的實例、hashcode、類的元數據信息指針(方法區)
執? init ?法(內核方法),初始化成員變量,執?實例化代碼塊,調?類的構造?法,并把堆內對象的?地址賦 值給引?變量。
CAS 加失敗重試保證更新原?性。
把內存分配按線程劃分在不同空間,即每個線程在 Java 堆中預先分配??塊內存,叫做本地線程分配緩沖 TLAB,哪個線程要分配內存就在對應的 TLAB 分配,TLAB ?完了再進?同步。
父類靜態成員和靜態初始化塊 ,按在代碼中出現的順序依次執行
子類靜態成員和靜態初始化塊 ,按在代碼中出現的順序依次執行
父類實例成員和實例初始化塊 ,按在代碼中出現的順序依次執行
父類構造方法
子類實例成員和實例初始化塊 ,按在代碼中出現的順序依次執行
子類構造方法
感謝各位的閱讀,以上就是“Java對象存儲內存布局的方法是什么”的內容了,經過本文的學習后,相信大家對Java對象存儲內存布局的方法是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。