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

Java 記憶體佔用深度解析:32 位元系統物件大小計算實戰

     編輯:Java 相關知識

前言:為何關注記憶體佔用?

常見情況:功能測試通過、初期記憶體佔用正常,但資料規模增長時記憶體暴增。根本原因在於不瞭解 Java 資料結構的真實記憶體開銷。本文基於 32 位元系統(64 位元系統不適用)實測總結,助您寫出高品質、記憶體高效的程式碼。

基礎類型記憶體佔用

類型byteshortintlongfloatdoublecharboolean
位元組12484821

範例:long[] data = new long[1000]; 佔用 8 × 1000 = 8000 bytes(陣列物件本身開銷可忽略)。

參考與物件核心結論

參考(Reference)佔 4 bytes

32 位元系統下,參考本質是受限指標,Object obj = null; 仍佔 4 bytes,Object[] objs = new Object[1000]; 至少佔 4000 bytes(全為 null 亦同)。

純 Object 物件佔 8 bytes(含物件頭),實際最少 12 bytes

Object obj = new Object(); // 8 bytes 物件內容 + 4 bytes 參考 = 12 bytes
Object[] objs = new Object[1000];
for (int i=0; i<1000; i++) objs[i] = new Object();
// 至少 12 × 1000 = 12000 bytes

JVM 物件對齊鐵律:大小必為 8 的倍數

此規則決定所有包裝類型大小:

  • Integer = Object(8) + int(4) = 12 → 對齊至 16 bytes
  • Byte、Short、Character、Boolean 同理皆為 16 bytes

陣列記憶體計算公式

基本類型陣列

byte[] bytes = new byte[1000]; 結構等同:

class Array { int length; byte byte0; byte byte1; ... byte byte999; }

計算:4(參考) + [8(物件頭) + 4(length) + 1×1000(元素)] = 4 + 1012 = 1016 → 對齊 1016 + 4 = 1020 bytes

小陣列驗證:new byte[4] = 4 + [8+4+4] = 20 bytes;new byte[3] 同為 20 bytes(對齊)。

物件參考陣列

Byte[] bytes = new Byte[1000]; 佔用:

陣列本體:4 + [8 + 4 + 4×1000] = 4020 bytes
1000 個 Byte 物件:16 × 1000 = 16000 bytes
總計 ≈ 20020 bytes(vs byte[] 1020 bytes,差 20 倍!)

結論:嚴禁使用 Byte[]、Integer[] 等包裝類型陣列處理大量資料!

自訂類別記憶體計算

規則:物件內容 = 8 bytes 基礎 + 所有欄位大小總和(物件欄位只算 4 bytes 參考),總大小對齊至 8 倍數,再加 4 bytes 參考。

class Abc { int n; byte b; Object obj; }
// 內容:8 + 4 + 1 + 4 = 17 → 對齊 24 bytes
// 實例:4 + 24 = 28 bytes

巢狀物件範例

class Abc { byte b; Object obj = null; }  // 內容 8+1+4=13→16 bytes,實例 20 bytes
class Def { int n; byte b; Abc obj = new Abc(); }
// Def 實例:4 + [8+4+1+4(Abc參考)] + [Abc實例 20] = 44 bytes

String 記憶體特性與優化

class String { 
    private final char[] value;  // 參考 4 bytes
    private final int offset;    // 4 bytes
    private final int count;     // 4 bytes
    private int hash;            // 4 bytes
}
// 最小 String 物件內容:8 + 4×4 = 24 bytes + 4 參考 = 28 bytes

精確計算:4 + 24 + [8 + 4 + 2×length](char[] 開銷)

  • String s = ""; → 28 + 16 = 44 bytes
  • String s = "ab"; → 28 + 16 = 44 bytes
  • String s = "abc"; → 28 + 24 = 52 bytes

JVM 字串常數池優化

String[] s = new String[1000];
for (int i=0; i<1000; i++) s[i] = new String("相同長字串");
// 佔用量級:28 × 1000 = 28000 bytes(字串內容僅一份!)

String 實際佔用介於 28~44 bytes 之間,極度記憶體友善。

實戰優化案例

原系統使用 Hashtable 儲存 100 萬元素,改為 String[] + int[] 陣列配合二分搜尋,記憶體佔用大幅改善,排序僅需 2 秒,查詢效能接近 Hash 表。

重要補充說明

  1. 僅適用 32 位元系統:64 位元系統雖可用記憶體更多,但同樣程式佔用顯著增加
  2. 不含靜態變數:靜態變數屬於 Class 資料,獨立計算
  3. 不含 Class 元資料:類結構、靜態欄位佔用為固定成本,不隨實例增加,統計需參考 JVM 原始碼 jclass 結構
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved