# 如何計算對象大小
1. 搞清楚Java對象的布局結構
2. 借助`jol-core`包來打印對象
3. 引用的指針壓縮
## 對象布局

## Java對象布局(Java Object Layout)
### String對象例子

### int[]數組對象例子

## 引用的指針壓縮
### JVM內存尋址最大內存是多少?
~~~
// 打印jvm的詳細信息
System.out.println(VM.current().details());
~~~
```
# Running 64-bit HotSpot VM. // 64位hotSpot虛擬機
# Using compressed oop with 3-bit shift. // 對象壓縮 3位無符號右移
# Using compressed klass with 3-bit shift. // 類型指針壓縮 3為無符號右移
# Objects are 8 bytes aligned. // 對象按8字節對齊
```
對象按8字節對齊,且jvm的引用占4個字節,能表示2^32=4G * 8 = 32G的物理內存。

### 不啟用指針壓縮
采用8字節(64位)存儲真實內存地址,比之前采用4字節(32位)壓縮存儲地址帶來的問題:
1. 增加了GC開銷:64位對象引用需要占用更多的堆空間,留給其他數據的空間將會減少,從而加快了GC的發生,更頻繁的進行GC。
2. 降低CPU緩存命中率:64位對象引用增大了,CPU能緩存的oop將會更少,從而降低了CPU緩存的效率。
### 啟用指針壓縮
* `-XX:+UseCompressedOops` 開啟指針壓縮,jdk6之后默認開啟。
* `-XX:+PrintFlagsFinal` 打印jvm參數,可以用來驗證檢查環境內的參數配置生效情況。
* 內存大于32GB時,開啟指針壓縮的參數會失效!
## 總結
對象大小 = 對象頭字節 + 實例數據字節 + 填充字節
## 參考資料
* 周志明 * 《深入理解Java虛擬機》
- 面試突擊
- Java虛擬機
- 認識字節碼
- 000Java發展歷史
- 000Macos10.15.7上編譯OpenJDK8u
- 001熟悉Java內存區域
- 002熟悉HotSpot中的對象
- 003Java如何計算對象大小
- 004垃圾判定算法與4大引用
- 005回收堆和方法區中對象
- 006垃圾收集算法
- 007HotSpot虛擬機垃圾算法實現篇1
- 007HotSpot虛擬機垃圾算法實現篇2
- 007HotSpot虛擬機垃圾算法實現篇3
- 008垃圾收集器
- 009內存分配與回收策略
- 010Java虛擬機相關工具
- 011調優案例分析
- 012一次IDEA的啟動速度調優
- 013類文件Class的結構
- 014熟悉字節碼指令
- 015類加載機制(過程)
- 016類加載器
- IDEA的JVM參數
- Java基礎
- Java自動裝箱與拆箱
- Java基礎數據類型
- Java方法的參數傳遞
- Java并發
- 001走入并行的世界
- 002并行程序基礎
- 003熟悉Java內存模型JMM
- 004Java并發之volatile關鍵字
- 005線程池入門到精通
- 006Java多線程間的同步控制方法
- 007Java維基準測試框架JMH
- 008Java并發容器
- 009Java的線程實現
- 010Java關鍵字synchronized
- 011一些并行模式的熟悉
- 單例模式和不變模式
- 生產者消費者模式
- Future模式
- 012一些并行算法的熟悉
- 面試總結
- 長亮一面