首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

JVM 調優總結(二):Java 物件大小計算與引用類型深度解析

     編輯:Java 相關知識

理解物件記憶體佔用與引用語義是 JVM 調優與排查 OOM 的基礎。

一、Java 物件大小計算規則

基礎:空 Object 物件

空 Object 物件在堆中佔用 8 bytes (僅含物件頭)。程式碼:

Object ob = new Object();

總佔用:4 bytes (棧中引用) + 8 bytes (堆中物件) = 12 bytes。
所有非基本型別物件預設繼承 Object,故**任何物件大小 ≥ 8 bytes (堆中)**。

實例:自訂物件大小計算


class NewObject {
    int count;      // 4 bytes
    boolean flag;   // 1 byte
    Object ob;      // 4 bytes (引用)
}

計算:8 (空物件) + 4 + 1 + 4 = 17 bytes。
對齊規則:JVM 物件記憶體分配按 8 的整數倍 對齊 → 最近的倍數為 24 bytes。

包裝類型記憶體開銷警示

  • 包裝類型已是物件,最小佔用 12 bytes (空物件頭),不含任何有效資料
  • 對齊後至少 16 bytes
  • 相較基本型別 (1~8 bytes),記憶體佔用 **N 倍 (N > 2)**,極為驚人

建議:盡量少用包裝類型。JDK 5.0+ 引入自動裝箱/拆箱,JVM 在儲存層面會優化,但邏輯層面仍需謹慎。

二、四種引用類型與 GC 行為

引用類型建立方式GC 回收行為典型用途
強引用 Object obj = new Object(); 嚴格判斷:被強引用 → **絕不回收** 一般物件持有,預設行為
軟引用 SoftReference<Object> ref = new SoftReference<>(obj); 視**剩餘記憶體**決定:記憶體緊張 → 回收;充裕 → 保留
OOM 發生時,系統中必無軟引用存活
**記憶體敏感型快取** (圖片快取、資料緩衝)
弱引用 WeakReference<Object> ref = new WeakReference<>(obj); GC 時**必定回收**,生命週期僅存於**單次 GC 週期**內 **非關鍵快取**、WeakHashMap 鍵、監聽器/回調持有
虛引用 PhantomReference<Object> ref = new PhantomReference<>(obj, queue); 無法單獨存活,**必須搭配 ReferenceQueue**;GC 時入隊列,供追蹤物件被回收時機 精確追蹤物件回收時機、DirectBuffer 清理、堆外記憶體管理

三、實務選型指南

  • 記憶體充足:直接用強引用做快取,可控性最高
  • 桌面應用/記憶體受限:軟/弱引用作快取較常見
  • 快取淘汰策略:軟引用適合「寧缺勿濫、記憶體緊張再清」;弱引用適合「下次 GC 必清」
  • 避免濫用:引用鏈過長會增加 GC 掃描開銷,ReferenceQueue 處理不當易洩漏

總結

物件大小 = 物件頭 (8B) + 實例欄位 + 對齊填充 (8 的倍數)。包裝類型開銷極大,能用基本型別堅決不用包裝。四種引用類型賦予開發者與 GC 協作的精細控制力,善用軟/弱引用可構建記憶體友善的快取體系,虛引用則是堆外資源管理的關鍵槓桿。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved