IBM i 開發者常面臨選擇:32 位元 JVM 啟動快、執行快、資源佔用少,但可定址記憶體遠小於 64 位元版本。若應用程式記憶體需求超出 32 位元上限,便被迫遷移至 64 位元 JVM。要精準評估記憶體需求,必須先理解 IBM i JVM 獨特的記憶體結構——Java Heap 與 Break Memory 的劃分與互動。
相對於受 GC 管理的 Heap Memory,Break Memory(又稱內部/私有記憶體)是 JVM 透過 C/C++ malloc 直接向作業系統申請的原生記憶體,主要供以下組件使用:
32 位元程式共擁 4 GB 位址空間(16 個 256 MB 分區)。Heap 與 Break Memory 共享 0x3–0xC 分區,且總額固定:Heap 預留越多,Break Memory 可用越少。
圖 1. 標準模式記憶體佈局
Heap 佔用 0x7–0xF 固定 9 區塊,並與 Break Memory 共享 0x3–0x6 區塊。
圖 2. 大 Heap 模式記憶體佈局
Heap 獨佔 0x3–0xF 共 13 區塊(3328 MB,32 位元極限),Break Memory 與主執行緒堆疊擠在 0x2 區塊(256 MB)。
圖 3. 超大 Heap 模式記憶體佈局
執行緒堆疊是 Break Memory 主要消耗者。假設每執行緒需 260 KB,可根據 -Xmx 設定推估可支援執行緒數上限:
Break Memory 可用空間與最大執行緒數對應關係
使用 STRSST → Advanced Analysis → JVMINFO -memory 查看詳細 Break Memory 分配。
圖 4. JVMINFO 輸出範例
圖形化介面直接顯示 Break Memory 大小與使用趨勢。
圖 5. WRKJVMJOB 輸出範例
| 版本 | 典型症狀 |
|---|---|
| V5R4 | JVM Crash(無法拋出 OOM,底層不支援分配檢查) |
| V6R1+ | 拋出 java.lang.OutOfMemoryError: unable to fork native thread;vlog 主代碼 0200 出現 <SYSCALL64>:AS_SETH(核心映射記憶體函式) |
MALLOCDEBUG=report_allocations 記錄所有 malloc 呼叫點。若減小 Heap 導致 Heap 本身 OOM,說明 32 位元位址空間已耗盡,唯有改用 64 位元 JVM 徹底解決。
本文剖析了 IBM i JVM 記憶體模型、Break Memory 分佈規律、監控工具與排錯路徑。Java 記憶體管理博大精深,掌握基礎後仍需持續深入鑽研,方能應對生產環境的複雜挑戰。