Java 對象(數組)佔多大空間(幾個字節) 手把手做實驗

廢話不多說,一起開幹

1 前置知識

本次實驗基於jdk8 64位以及以上版本。本機環境爲jdk11
在這裏插入圖片描述
先查看一下jvm啓動的默認參數,裏面有2個參數值對本次實驗會造成影響。
命令行: java -XX:+PrintCommandLineFlags -version 查看jvm默認參數
在這裏插入圖片描述

分別是 -XX:+UseCompressedOops 和 -XX:+UseCompressedClassPointers
這2個參數都是默認開啓(+代表開啓,-代表關閉)

UseCompressedOops:普通對象指針壓縮(oop是ordinary object pointer的縮寫),
UseCompressedClassPointers:類型指針壓縮。

從字面意思很容易理解。
舉個例子說明一下: Object o = new Object();
o指向new Object()的引用就是“普通對象指針”,
new Object()自身還需要指向Object類型的引用,也就是"類型指針"。

這2個壓縮參數可以有4種組合(++, --, + -, -+),但有1種組合是會拋出警告的:

-XX:+UseCompressedClassPointers -XX:-UseCompressedOops,不要使用這種參數組合,用這種參數啓動jvm時會拋出警告。

原因是jvm層面的hotspot源碼對jvm的參數組合做了限制,一看就懂:

在這裏插入圖片描述
請大家有個印象,這2個參數在開啓壓縮時是佔4個字節,關閉壓縮時是佔8個字節。馬上開始進行我們的實驗。

2 對象的內存存儲佈局

在這裏插入圖片描述
下面使用JOL庫(Java Object Layout)來分析查看對象的內存佈局,JOL庫是openjdk中分析JVM中對象佈局的工具庫。

新建1個maven項目,引入

<dependency>
  <groupId>org.openjdk.jol</groupId>
  <artifactId>jol-core</artifactId>
  <version>0.9</version>
</dependency>

依賴即可使用。

2.1 使用默認參數-XX:+UseCompressedClassPointers -XX:+UseCompressedOops開啓壓縮啓動程序,打印出Person對象的內存佈局,進行詳細說明。

在這裏插入圖片描述
Person對象合計佔用32字節。

2.2 使用參數關閉壓縮-XX:-UseCompressedClassPointers -XX:-UseCompressedOops啓動程序,打印出Person對象的內存佈局,進行對比說明

在這裏插入圖片描述

Person對象合計佔用40字節。

3 數組的內存存儲佈局

在這裏插入圖片描述

使用默認參數-XX:+UseCompressedClassPointers -XX:+UseCompressedOops啓動程序,打印出數組對象的內存佈局,進行詳細說明。
在這裏插入圖片描述
new Long[5]佔用40字節,new long[5]佔用56字節。

關閉指針壓縮參數的例子就不詳細再寫了,各位可以自行嘗試。

關於boolean值(比較特殊的基本類型)也做了實驗,大家可以自己分析下,看和自己設想的是否一致:
在這裏插入圖片描述
同時也可以利用jol庫對自己其他想驗證的想法進行試驗驗證。

demo示例代碼, 需要的自取: https://github.com/wanjinyu1988/joldemo.git

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