1. 程式人生 > >「每日五分鐘,玩轉JVM」:物件記憶體佈局

「每日五分鐘,玩轉JVM」:物件記憶體佈局

概覽

一個物件根據不同情況可以被劃分成兩種情況,當物件是一個非陣列物件的時候,物件頭,例項資料,對齊填充在記憶體中三分天下,而陣列物件中在物件頭中多了一個用於描述陣列物件長度的部分

物件頭

物件頭分為兩部分,第一部分稱之為"Mark Word",第二部分是用於獲取該物件型別的型別指標,如果是陣列物件還包括記錄陣列長度的資料。

在不同的作業系統中,這些區域所佔的記憶體也不同,在32位的系統中,MarkWord佔用32bit的空間(也就是4位元組)。型別指標和陣列長度資料一樣合作佔用32bit的空間。

在64位的作業系統中,MarkWord佔用64bit的空間,型別指標在不開啟指標壓縮(CompressedOOPs)的情況下是64bit(8 byte),而在開啟指標壓縮的情況下,僅剩32bit(4 byte)

Mark Word

這一部分儲存的是物件自身的執行時資料,這一塊兒內容的資料結構並不固定,它會根據物件的狀態複用自己的儲存空間,

這是摘自markOop.hpp檔案中的片段,其中表示了物件的以下五種狀態:

標誌位 偏向鎖標識位 狀態
01 0 無鎖
01 1 偏向鎖
00 輕量級鎖
10 重量級鎖
11 GC Mark

我們接下來接著去看MarkWord的結構:

在這裡我們可以看到,初始化的時候只是定義了無鎖和偏向鎖狀態的結構(上半部分是沒有開啟COOPs-指標壓縮的結構,下半部分是開啟了指標壓縮的結構),

當處於輕量級鎖、重量級鎖時,記錄的物件指標,根據JVM的說明,此時認為指標仍然是64位,最低兩位假定為0;當處於偏向鎖時,記錄的為獲得偏向鎖的執行緒指標,該指標也是64位;

更多的內容我們就不再這裡擴充套件了,根據反饋的情況,我會在後面併發程式設計中單開一篇來聊聊鎖的進化之路。

型別指標

這個東西有時候會用到去確定該物件屬於哪個類的例項,也有用不到的時候,這個要根據不同的虛擬機器對於物件的定位實現演算法的選擇來進行(比如HotSpot JVM就使用該型別指標去獲取該物件型別資料)

例項資料

例項資料是物件真正儲存的有效資訊,也是在程式程式碼中所定義的各種型別的欄位內容,這裡的欄位內容不僅僅包括當前類的欄位,也包括他的父類中所定義的欄位。

這部分的儲存規則遵循虛擬機器分配策略引數和欄位在Java原始碼中的定義順序,HotSpot JVM預設的分配策略是long/double, int,short/char,byte/boolean,oops(普通物件指標,Ordinary Object Pointers)也可以理解為reference,關於指標壓縮我們下節去說。

這裡需要注意,在父類中定義的變數會出現在子類前,但是我們可以通過將CompactFileds引數設定為true,將子類中較小的變數插入到父類大變數的空隙中。

對齊填充

這部分內容並不是必須存在的,因為Hot Spot JVM中規定了物件的大小必須是8位元組的整數倍,在C/C++中類似的功能被稱之為記憶體對齊,記憶體空間都是按照 byte 劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何地址開始,但實際情況是在訪問特定型別變數的時候經常在特定的記憶體地址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的一個接一個的排放,這就是對齊。

記憶體對齊遵循兩個規則:

  • 假設第一個成員的起始地址為0,每個成員的起始地址(startpos)必須是其資料型別所佔空間大小的整數倍

  • 結構體的最終大小必須是其成員(基礎資料型別成員)裡最大成員所佔大小的整數倍。

這裡也就不難理解為什麼JVM規定物件的大小必須是8位元組的整數倍了,因為在64位系統下(不開啟指標壓縮),物件中存在很多佔用8 byte的資料型別。但是同時也存在一些4 byte的資料型別,這時我們的Padding就起到了作用,去補充不滿8 byte的部分,湊齊8的整數倍。

公眾號

相關推薦

每日分鐘JVM物件記憶體佈局

概覽 一個物件根據不同情況可以被劃分成兩種情況,當物件是一個非陣列物件的時候,物件頭,例項資料,對齊填充在記憶體中三分天下,而陣列物件中在物件頭中多了一個用於描述陣列物件長度的部分 物件頭 物件頭分為兩部分,第一部分稱之為"Mark Word",第二部分是用於獲取該物件型別的型別指標,

每日分鐘JVM物件從哪來

面向物件 眾所周知,Java是一門面向物件的高階程式語言,那麼現在問題來了,物件從哪來呢?有些人會說通過new關鍵字來建立一個物件,說的很好,本篇我們就來解密在new一個物件的過程中,JVM都給我們做了什麼工作。 走哪來,到哪去 一個物件的誕生必定有一個類,通常我們都是通過new關鍵字例項化一個類來獲取該類的

每日分鐘JVM執行緒獨佔區

前言 如果我們對計算機組成有所瞭解,那麼我們一定會知道在計算機中有一塊兒特殊的區域,稱之為暫存器,暫存器包括了指令暫存器和程式計數器,這兩樣位於CPU中,作為程式執行的大腦來控制程式的執行和流轉。 而在JVM中,作為一種虛擬機器,JVM沒有指令暫存器,它是基於棧 + 程式計數器的體系結構來完成方法的執行,之所

每日分鐘JVM執行緒共享區

前言 上一篇中,我們瞭解了JVM中的執行緒獨佔區,這節課我們就來了解一下JVM中的執行緒共享區,JVM中的執行緒共享區是跟隨JVM啟動時一起建立的,包括堆(Heap)和方法區()兩部分,而執行緒獨佔區的程式計數器,虛擬機器棧,本地方法棧的生命週期都是跟隨執行緒的,隨執行緒的建立而誕生,隨執行緒的銷燬而銷燬。

每日分鐘 JVMGC 概覽

前言 GC(Garbage Collection)是我們在學習 JVM 的過程中不可避免的一道坎,接下來,我們就來系統的學習一下 GC。 做一件事情之前,我們一定要去知道我們為什麼要去做,這裡不僅僅指 GC,更適用我們日常的學習和生活,知其然,知其所以然,方能百戰不殆。 下面我們先去了解為什麼要有 GC,

每日分鐘JVM指標壓縮

64位JVM和32位JVM 最初的時候,JVM是32位的,但是隨著64位系統的興起,JVM也迎來了從32位到64位的轉換,32位的JVM對比64位的記憶體容量比較有限,但是我們使用64位虛擬機器的同時,也帶來了一個問題,64位下的JVM中的物件會比32位中的物件多佔用1.5倍的記憶體空間,這是我們不想看到的

每天分鐘 JVM物件訪問定位

### 前言 在「物件記憶體佈局」一節中,我們瞭解到物件頭中包含了一個叫做**型別指標**的東西,即物件指向它的類元資料的指標,虛擬機器通過這個指標來確定這個物件是哪個類的例項。但是,並不是所有的虛擬機器都是這麼去做的。不同的虛擬機器關於這點有不同的實現,目前主流的方式可以分為**控制代碼**和**直接指標

JVM學習之物件記憶體佈局物件

本篇內容來自《深入理解Java虛擬機器_JVM高階特性與最佳實踐》,感謝作者。 建立物件之後需要使用物件,java中除了對物件屬性方法的呼叫以外還有加鎖實現同步等其他操作,這裡的鎖加在了哪裡,如何記錄鎖,如何對鎖進行分類(有物件鎖,class鎖),垃圾回收機制中有關於GC的

ThinkPHP分頁用異步來做分頁類!

sse replace xpage private 替換 string 設置 nbsp urlencode 具體為什麽用異步來做分頁我就不多說了! 用異步來做分頁,主要還是看分頁類怎麽玩! 方便管理,還是把Ajax分頁作為一個工具來使用: 同樣新建工具類: 多次嘗試,最終

忘記Ghost!利用Win10自帶功能系統備份&恢復 -- 關於恢復的深度思考

如果 mage 不能啟動 技術 硬盤 blog 引導 系統版本 bsp 上一篇文章講了,系統可以正常啟動,如何從D盤恢復系統到C盤的情況。 如果系統不能啟動,要怎麽去恢復系統,恢復後會是什麽結果? 先說明系統結構: 系統版本:Windows 10 (1709) 硬盤1(

【程序員的吃雞大法】利用OCR文字識別+百度算法搜索沖頂大會、百萬英雄、芝士超人等答題贏獎金遊戲

amp lec ios 結果 round 去百度 方式 英雄 oid 【先上一張效果圖】: 一、原理: 其實原理很簡單: 1.手機投屏到電腦; 2.截取投屏畫面的題目部分,進行識別,得到題目和三個答案; 3.將答案按照一定的算法,進行搜索,得出推薦答案; 4.添加了一

zookeeper-1.操作與應用場景-《每日分鐘搞定大數據》

分享 似的 每日 文件 實現 多個 tasks 回復 task Zookeeper作為一個分布式協調系統提供了一項基本服務:分布式鎖服務,分布式鎖是分布式協調技術實現的核心內容。像配置管理、任務分發、組服務、分布式消息隊列、分布式通知/協調等,這些應用實際上都是基於這項

啟程 - 《每日分鐘搞定大數據》

alt 系列 梳理 分享 視頻 了解 href http 不定 ??想了很久,準備開始寫一系列的文章,記錄這些年來的所得所想,感覺內容比較多不知從哪裏開始,畫了個思維導圖確定了大的方向,內容會不斷添加。細節的東西我會邊寫邊定,大家也可以給我一些建議,我會根據寫的內容實時更

YARN-異常大全-《每日分鐘搞定大數據》

管理 cat love guarantee 解決 code 出現 shu sources #問題描述:NodeManager1 cpu負載飆高,進程還在但是不再向ResourceManager發送心跳,不斷重復下文2的動作。心跳停止一段時間後會重連上RM但是cpu仍然很高,

一篇文章搞懂DataSet、DataFrame、RDD-《每日分鐘搞定大數據》

implicit 操作數 frame 大數據 函數 for 臨時 變量 ade 1. 三者共性: 1、RDD、DataFrame、Dataset全都是spark平臺下的分布式彈性數據集,為處理超大型數據提供便利 2、三者都有惰性機制,執行trainform操作時不會立即執

你願意給我分鐘讓我帶你掌握正則表示式嗎?爬蟲必會知識點!

今天小編給大家分享的是Python正則表示式的簡單應用和示例演示,將前面學習的Python正則表示式做一個概括。       進群:548377875  即可獲取大量的零基礎學習資料以及從零基礎到專案實戰的PDF一套哦! &nb

zookeeper-操作與應用場景-《每日分鐘搞定大資料》

Zookeeper作為一個分散式協調系統提供了一項基本服務:分散式鎖服務,分散式鎖是分散式協調技術實現的核心內容。像配置管理、任務分發、組服務、分散式訊息佇列、分散式通知/協調等,這些應用實際上都是基於這項基礎服務由使用者自己摸索出來的。 1.Zookeeper在大資

Android圖片載入框架最全解析(四)Glide的回撥與監聽(筆記)

參考原文:Android圖片載入框架最全解析(四),玩轉Glide的回撥與監聽 回撥的原始碼實現 的Target物件傳入到GenericRequest當中,而Glide在圖片載入完成之後又會回撥GenericRequest的onResourceReady()方法,onReso

10個密信(MeSince)使用技巧郵件加密!

密信(MeSince)加密郵件客戶端不僅提供郵件收發及加解密等郵件核心功能,同時在多個方面提供創新功能、提升使用者體驗。以下10個密信(MeSince)使用技巧,帶您玩轉郵件加密!   下載安裝 密信(MeSince)加密郵件客戶端,支援iOS、安卓、Windows版

jvm系列 02】物件探祕

注意:本文描述的內容是基於HotSpot虛擬機器。 物件的建立 物件建立流程圖 物件建立流程 虛擬機器遇到一條new指令 檢查該指令引數在常量池中能否定位到對應類的符號引用 檢查該類是否被載入、解析和初始化,如果沒有必須先執行載入過程