日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

硬核 JVM 壓縮指針詳解

來源: 責編: 時間:2023-10-13 14:37:06 278觀看
導讀一、前言當今,Java已經成為了世界上最流行的編程語言之一。在Java的生態系統中,JVM(Java虛擬機)是至關重要的組成部分。JVM 是 Java 程序運行的環境,它負責將 Java 字節碼翻譯成機器碼,并執行程序。在 JVM 中,內存使用以及分

一、前言

當今,Java已經成為了世界上最流行的編程語言之一。在Java的生態系統中,JVM(Java虛擬機)是至關重要的組成部分。JVM 是 Java 程序運行的環境,它負責將 Java 字節碼翻譯成機器碼,并執行程序。在 JVM 中,內存使用以及分配一直是個重要的問題。
EB628資訊網——每日最新資訊28at.com

在 32 位系統中,一枚指針占用 4 字節,隨著 64 位系統的逐漸普及,指針的大小也增長到了 8 個字節,JVM 為了降低內存占用,使用了指針壓縮技術來降低內存的占用,接下來,我們將自頂向下的深入探討 JVM 指針壓縮的工作原理。EB628資訊網——每日最新資訊28at.com

二、理解壓縮指針

為什么 JVM 需要壓縮指針?

在計算機中,指針的大小通常取決于計算機的字長。例如,在 32 位系統一字長為 4 字節,即一枚指針的占用內存空間大小為 4 字節。隨著計算機性能的提升,內存價格的降低,64 位系統也開始逐漸普及。而在 64 位系統中,字長和指針也由原來的增長到 8 個字節,JVM 為了降低內存占用,開發了指針壓縮算法,即:在 64 位系統中,指針依然使用 4 字節存儲。
EB628資訊網——每日最新資訊28at.com

數據指針與字長的關系

字長是指一臺計算機中處理器可以一次性處理的二進制數字的位數。它通常是 8 位、16 位、32 位或 64 位,這意味著在一次處理中可以處理 8 個、16 個、32 個或 64 個二進制數字。字長越長,計算機處理數據的能力越強,但同時也會增加計算機的成本和復雜度。
EB628資訊網——每日最新資訊28at.com

CPU 的上下文是寄存器,CPU 運算的本質就是不斷從 CS IP 寄存器中取指令然后執行,CPU 運算所需的數據也是放在寄存器里,CPU 一次性處理的數據大小就是寄存器的大小。EB628資訊網——每日最新資訊28at.com

圖片圖片EB628資訊網——每日最新資訊28at.com

上圖左側是一段簡單的 C 語言代碼片段,右側是該代碼的匯編代碼(即 CPU 執行這段代碼的實際機器碼的解釋)。EB628資訊網——每日最新資訊28at.com

圖片圖片EB628資訊網——每日最新資訊28at.com

CPU 執行計算時,需要先將數據讀取到寄存器,存取內存中的變量時,是直接操作變量所在地址及偏移量,而變量所在地址(即指針)也是存儲在寄存器中的,因此寄存器大小直接決定了 CPU 所能訪問內存的地址空間。因此,在 32 位系統中,寄存器的最大長度是 32 bit(即 4 個字節),因此最大支持訪問 4GB 的內存空間,在 64 位系統中,寄存器最大 64 bit(即 8 字節)。而數據的指針由于需要指向整個內存空間,因此也就是 8 字節。8 字節大小的指針所能允許訪問的最大地址為:16EB(16384PB=16777216TB=17179869184GB)的內存空間。EB628資訊網——每日最新資訊28at.com

所以字長其實就等于寄存器的大小,指針為了能指向整個內存空間,通常也等于字長大小。EB628資訊網——每日最新資訊28at.com

理解內存對齊

這是一段簡單的 C 語言代碼:
EB628資訊網——每日最新資訊28at.com

#include <stdio.h>struct Test {    int a;    char b;    int c;} test;int main(void) {    test.a = 1;    test.b = 2;    test.c = 3;    printf("struct Test size: %d/n", sizeof(test));    return 0;}

在 C 語言中,結構體數據是連續的,Int 為 4 字節,Char 為 1 字節,所以 Struct Test 為 9 字節。EB628資訊網——每日最新資訊28at.com

但是實際輸出結果卻是 12 字節:EB628資訊網——每日最新資訊28at.com

圖片圖片EB628資訊網——每日最新資訊28at.com

圖片圖片EB628資訊網——每日最新資訊28at.com

通過匯編指令可以分析出,結構體 Test 的內存布局如下:EB628資訊網——每日最新資訊28at.com

圖片圖片EB628資訊網——每日最新資訊28at.com

可以看出,在 Char 類型數據后面被空出了 3 個字節的位置,原因如下:EB628資訊網——每日最新資訊28at.com

計算機只能從 4 字節的整數倍開始尋址,如果在 Char b 后不進行空數據填充,則編譯后的指令會很長,極大的降低 CPU 執行效率:EB628資訊網——每日最新資訊28at.com

圖片圖片EB628資訊網——每日最新資訊28at.com

所以在 JVM 中,對象的存儲也是如此設計:EB628資訊網——每日最新資訊28at.com

class Test {    int a;    char b;    int c;}

對象布局如下:EB628資訊網——每日最新資訊28at.com

圖片圖片EB628資訊網——每日最新資訊28at.com

可以看出 Char b 數據后空出了 3 個字節的內存空間作為 Padding, 以供后面的對象進行內存對齊。EB628資訊網——每日最新資訊28at.com

為什么計算機只能從特定地址讀取數據?

計算機之所以只能從特定地址開始讀取數據,是由于在內存中存儲的物理位置導致的。
EB628資訊網——每日最新資訊28at.com

圖片圖片EB628資訊網——每日最新資訊28at.com

這是一根內存條,上面有 4 個內存顆粒(Chip),在我們聲明一個變量 Int a = 1;時,CPU 想一次從內存中同時取出 32 位數據,為了發揮并行傳輸數據的能力,同時與 4 個內存顆粒進行交互肯定比一個內存交互要快,因此數據 a 分別在 4 個顆粒中存儲 0x01 0x00 0x00 0x00。EB628資訊網——每日最新資訊28at.com

圖片圖片EB628資訊網——每日最新資訊28at.com

每個內存顆粒 Chip 中有 8 個 bank,每次同時從 8 個 bank 中取一位數據。EB628資訊網——每日最新資訊28at.com

圖片圖片EB628資訊網——每日最新資訊28at.com

為了盡可能節約地址總線位數,變量 a 的每字節數據在各 Chip 中相對位置是相同的,每字節中的每位數據在 bank 中的行數和列數也是相同的。EB628資訊網——每日最新資訊28at.com

總結,為了能利用有限的地址總線,盡量快速尋址到盡可能多的數據,在設計計算機時取了巧,CPU 同時只能訪問 32 個相對地址相同的數據位,表現上就是只能從被 4 字節整除的地址開始尋址。EB628資訊網——每日最新資訊28at.com

理解指針壓縮

在 64 位系統中,JVM 為了降低 8 字節的指針對內存的占用,使用了指針壓縮的技術,將 8 字節的指針壓縮為 4 字節。
EB628資訊網——每日最新資訊28at.com

前面說到,JVM 出于性能考慮,對數據做了對齊到 4 字節的處理,因此指針的值末尾 5 bit 始終為 0B11111。JVM 的指針壓縮算法就是,把本來應該使用 8 個字節的指針,直接改為 4 字節的進行代替,那么 4 字節的指針實際最高可以表示 32G 的內存空間。這也就是為什么當物理內存超過 32G 時,需要關閉 JVM 指針壓縮。EB628資訊網——每日最新資訊28at.com

三、實戰解碼指針

工具介紹

HSDB

HSDB(HotSpot Debugger),是一個用于 HotSpot 虛擬機的調試工具。它提供了一種可視化的方式來查看和調試 Java 應用程序在 JVM 上的運行情況。HSDB 可以用于分析線程、堆、類、對象、方法、編譯器和代碼緩存等方面的信息。它還可以用于監視虛擬機性能和調試垃圾回收器。HSDB 是一個非常強大的工具,可以幫助開發人員更好地理解和優化 Java 應用程序的性能。EB628資訊網——每日最新資訊28at.com

官方提供的 HSDB 命令行不是很好用,比如命令補全、命令提示、光標移動、命令歷史記錄等都不存在,所以本次分享講利用 PerfMa 開源的 XPocket 工具,配合 HSDB 插件來操作。EB628資訊網——每日最新資訊28at.com

XPocket 工具

XPocket 是 PerfMa 為解決性能問題而生的開源的插件容器,它是性能領域的樂高,將定位或者解決各種性能問題的常見的 Linux 命令,JDK 工具,知名性能工具等適配成各種 XPocket 插件,并讓它們可以相互聯動一鍵解決特定的性能問題。目前 XPocket 插件生態已經實現了 HSDB、JDB、JConsole、Perf、Arthas 等多個優秀的開源性能工具的插件化集成。EB628資訊網——每日最新資訊28at.com

快速開始

下載 XPocket,然后解壓運行。
EB628資訊網——每日最新資訊28at.com

wget https://a.perfma/xpocket/download/XPocket.tar.gztar -xvf  XPocket.tar.gzsh xpocket/xpocket.sh

圖片圖片EB628資訊網——每日最新資訊28at.com

# 切換至 HSDB 插件空間XPocket [system] > use jhsdb@JDK# 啟動 clhsdb 命令行XPocket [jhsdb] > clhsdb# attach 到目標進程XPocket [jhsdb] > attach 29516

利用 HSDB 查看 JVM 對象內存布局

準備工作

編寫一個測試類,啟動 JVM 進程。EB628資訊網——每日最新資訊28at.com

@Data@Componentpublic class BeanTest {    private long l = 1;    private BeanTest pointer = this;    private int i = 2;    private boolean b = false;    private char c = 3;    private BeanTest[] arr = {this};}

想要查看對象的內存布局,首先要找到這個對象所在位置,JVM 的對象分布在堆上,可以通過 Universe 命令確定堆內的相關區域對應位置。EB628資訊網——每日最新資訊28at.com

# 執行以下命令,切換至 HSDB 插件XPocket [system] > use jhsdb@JDK# 啟動 HSDB 插件XPocket [jhsdb] > clhsdb# 通過 jps 命令,查詢 JVM 進程的 pid,attach 到這個 JVM 進程XPocket [jhsdb] > attach 29516# 執行 universe 命令,查看堆內存分布情況XPocket [jhsdb : 29516] > universe

內存分布情況如下:EB628資訊網——每日最新資訊28at.com

圖片圖片EB628資訊網——每日最新資訊28at.com

括號內的第一個值為內存起始位置,第二個值為已使用的位置,第三個值為該區域最大地址。以上圖 eden 區為例:EB628資訊網——每日最新資訊28at.com

eden 區空間范圍為:0x00000000fab00000 ~ 0x00000000fef00000,相減得到 71303168,68MB。EB628資訊網——每日最新資訊28at.com

eden 區已使用空間為:0x00000000fab00000 ~ 0x00000000fafd2a60,相減得到 5057120,4.82M。EB628資訊網——每日最新資訊28at.com

找到我們定義的對象

我們要找的對象是受 Spring 管理的,所以很容易判斷,通常情況下都會在老年代里。那么我們直接在老年代內檢索這個對象即可。由于 Oop(簡單對象指針)是所有 Java 對象的基類,所以我們可以利用 Scanoops 命令來檢索這個對象。EB628資訊網——每日最新資訊28at.com

XPocket [jhsdb : 29516] > scanoops 0x00000000f0000000 0x00000000f1265ca8 com.poizon.robot.test.BeanTest

檢索到的結果如下:EB628資訊網——每日最新資訊28at.com

圖片圖片EB628資訊網——每日最新資訊28at.com

0x00000000f1060898 是這個對象實例的內存地址,也就是該對象的指針值。EB628資訊網——每日最新資訊28at.com

查看對象內存布局

然后我們就可以通過 Inspect 命令來查看該對象的內存布局了。EB628資訊網——每日最新資訊28at.com

XPocket [jhsdb : 29516] > inspect 0x00000000f1060898

得到結果如下:EB628資訊網——每日最新資訊28at.com

圖片圖片EB628資訊網——每日最新資訊28at.com

注意:這里顯示的數據是按照類變量順序來展示的,并非實際結構EB628資訊網——每日最新資訊28at.com

由圖返回結果可以看出, BeanTest 對象大小為 40 字節,當前系統為 X64 架構,一個字長為 8 字節,即此對象占用 5 個字長。執行 Mem 命令,獲取整個對象(5 個字長)的數據。EB628資訊網——每日最新資訊28at.com

XPocket [jhsdb : 29516] > mem 0x00000000f1060898 5

得到結果如下:EB628資訊網——每日最新資訊28at.com

圖片圖片EB628資訊網——每日最新資訊28at.com

左側為當前字長的數據起始地址,右側為數據值。EB628資訊網——每日最新資訊28at.com

我們再來復習一遍對象頭(Oop數據),前 8 位是 Mark Word,后 8 位中,如果開啟了指針壓縮,則前 4 位為當前實例所在類的指針,后 4 位填充當前對象 <=4 字節的數據(Gap Padding);如果未開啟指針壓縮,則該 8 位為當前實例對所在類的指針。EB628資訊網——每日最新資訊28at.com

查找類的指針

我們這次啟動的進程開啟了指針壓縮,把第二個字長的數據(0x000000022007a2bb)按 4 字節拆成兩部分:EB628資訊網——每日最新資訊28at.com

0x00000002:BeanTest 對象中只有一個值為 2 ,所以該值是Int i = 2;EB628資訊網——每日最新資訊28at.com

0x2007a2bb(類指針):前面說過,指針壓縮的原理只是簡單的把 8 字節指針削減為 4 字節,因為后 5 位始終為 0,因此若要還原壓縮后的指針實際內存地址,直接把指針值 * 8即可。EB628資訊網——每日最新資訊28at.com

BeanTest 類所在地址為:0x2007a2bb * 8 = 0x1003D15D8EB628資訊網——每日最新資訊28at.com

執行 Inspect 命令,查看 BeanTest 類結構。EB628資訊網——每日最新資訊28at.com

XPocket [jhsdb : 29516] > inspect 0x1003D15D8

結果如下:EB628資訊網——每日最新資訊28at.com

圖片圖片EB628資訊網——每日最新資訊28at.com

證實

BeanTest 在 JVM 對象為 c++ 的 InstanceKlass 實例,可以看出 _name 屬性為 Symbol,接下來查看 InstanceKlass _name 屬性,證實當前為 BeanTest 類的實例,執行 Symbol 命令查看 _name 的值:EB628資訊網——每日最新資訊28at.com

XPocket [jhsdb : 29516] > symbol 0x00007f1838abb740

圖片圖片EB628資訊網——每日最新資訊28at.com

證實 0x1003D15D8 所在的內存地址,即是 com.poizon.robot.test.BeanTest 的 Class 對象。EB628資訊網——每日最新資訊28at.com

四、總結

在我們日常開發中遇到的一點小小的,看似不起眼的奇怪的規范,深挖之下往往能夠牽扯出一大串知識體系,保持好奇心刨根問底同樣也是很重要學習方法。有興趣的同學也可以自己嘗試找一下示例類中其他屬性所對應的 Class 指針,說不定還可以對網上的一些文章做一次勘誤呢~EB628資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-13297-0.html硬核 JVM 壓縮指針詳解

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: WhatsApp 僅用 32 名工程師就能支持每天 500 億條消息的八個原因

下一篇: 如何使用Otseca搜索和轉儲系統配置并生成HTML報告

標簽:
  • 熱門焦點
  • K60 Pro官方停產 第三方瞬間漲價

    雖然沒有官方宣布,但Redmi的一些高管也已經透露了,Redmi K60 Pro已經停產且不會補貨,這一切都是為了即將到來的K60 Ultra鋪路,屬于廠家的正常操作。但有意思的是該機在停產之后
  • 直屏旗艦來了 iQOO 12和K70 Pro同臺競技

    旗艦機基本上使用的都是雙曲面屏幕,這就讓很多喜歡直屏的愛好者在苦等一款直屏旗艦,這次,你們等到了。據博主數碼閑聊站帶來的最新爆料稱,Redmi下代旗艦K70 Pro和iQOO 12兩款手
  • 小米平板5 Pro 12.4簡評:多專多能 兼顧影音娛樂的大屏利器

    疫情帶來了網課,網課盤活了安卓平板,安卓平板市場雖然中途停滯了幾年,但好的一點就是停滯的這幾年行業又有了新的發展方向,例如超窄邊框、高刷新率、多攝鏡頭組合等,這就讓安卓
  • Java NIO內存映射文件:提高文件讀寫效率的優秀實踐!

    Java的NIO庫提供了內存映射文件的支持,它可以將文件映射到內存中,從而可以更快地讀取和寫入文件數據。本文將對Java內存映射文件進行詳細的介紹和演示。內存映射文件概述內存
  • 一文搞定Java NIO,以及各種奇葩流

    大家好,我是哪吒。很多朋友問我,如何才能學好IO流,對各種流的概念,云里霧里的,不求甚解。用到的時候,現百度,功能雖然實現了,但是為什么用這個?不知道。更別說效率問題了~下次再遇到,
  • ESG的面子與里子

    來源 | 光子星球撰文 | 吳坤諺編輯 | 吳先之三伏大幕拉起,各地高溫預警不絕,但處于厄爾尼諾大&ldquo;烤&rdquo;之下的除了眾生,還有各大企業發布的ESG報告。ESG是&ldquo;環境保
  • 機構稱Q2全球智能手機出貨量同比下滑11% 蘋果份額依舊第2

    7月20日消息,據外媒報道,研究機構的報告顯示,由于需求下滑,今年二季度全球智能手機的出貨量,同比下滑了11%,三星、蘋果等主要廠商的銷量,較去年同期均有下
  • 滴滴違法違規被罰80.26億 共存在16項違法事實

    滴滴違法違規被罰80.26億 存在16項違法事實開始于2121年7月,歷經一年時間,網絡安全審查辦公室對“滴滴出行”網絡安全審查終于有了一個暫時的結束。據“網信
  • 最薄的14英寸游戲筆記本電腦 Alienware X14已可以購買

    2022年1月份在國際消費電子展(CES2022)上首次亮相的Alienware新品——Alienware X14現在已經可以購買了,這款筆記本電腦被譽為世界上最薄的 14 英寸游戲筆
Top 主站蜘蛛池模板: 宕昌县| 洮南市| 青田县| 商洛市| 奉贤区| 马山县| 陇川县| 尼木县| 碌曲县| 涟水县| 卓尼县| 旌德县| 绥宁县| 阜平县| 古丈县| 大埔区| 佳木斯市| 陆河县| 丹凤县| 历史| 海林市| 望江县| 聊城市| 周宁县| 大丰市| 法库县| 乌海市| 斗六市| 阿瓦提县| 康马县| 兰考县| 文安县| 水城县| 延津县| 祥云县| 南汇区| 新乡县| 淳化县| 将乐县| 内黄县| 佛坪县|