Integer.MAX_VALUE (2^31-1),byte[] 最大 2 GB,long[] 最大 16 GB (需 -Xmx 足夠大)。-Xmx 及作業系統程序虛擬記憶體。DirectByteBuffer 受 -XX:MaxDirectMemorySize 控制,預設與 -Xmx 相同。// 邏輯上 16 GB,物理上分段
List chunks = new ArrayList<>();
for (int i = 0; i < 8; i++) chunks.add(new byte[2_000_000_000]); // 8 x 2GB
// 存取時計算 chunkIndex + offset
優點:純 Java、GC 管理。缺點:存取需額外計算、記憶體碎片化。
sun.misc.Unsafe 可繞過陣列長度檢查,直接按位元組偏移讀寫任意型別。
import sun.misc.Unsafe;
import java.lang.reflect.Field;
public class UnsafeArrayAccess {
static final Unsafe UNSAFE;
static final long BYTE_ARRAY_OFFSET;
static {
try {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
UNSAFE = (Unsafe) f.get(null);
BYTE_ARRAY_OFFSET = UNSAFE.arrayBaseOffset(byte[].class);
} catch (Exception e) { throw new Error(e); }
}
public static void main(String[] args) {
byte[] arr = new byte[1000];
long addr = BYTE_ARRAY_OFFSET + 500; // 第 500 位元組
UNSAFE.putByte(arr, addr, (byte) 0xFF);
System.out.println("直接寫入: " + (arr[500] & 0xFF)); // 255
}
}
⚠️ JDK 9+ 模組化封鎖:需加 --add-exports java.base/jdk.internal.misc=ALL-UNNAMED,或改用 VarHandle (JDK 9+ 官方替代)。
public class OffHeapMemory {
static final Unsafe U = getUnsafe();
public static void main(String[] args) {
long size = 4L * 1024 * 1024 * 1024; // 4 GB 離堆
long addr = U.allocateMemory(size);
try {
// 寫入測試
for (long i = 0; i < size; i += 4096) U.putByte(addr + i, (byte) 1);
// 讀取驗證
for (long i = 0; i < size; i += 4096) {
if (U.getByte(addr + i) != 1) throw new AssertionError("驗證失敗 at " + i);
}
System.out.println("4 GB 離堆讀寫成功,位址: " + addr);
} finally {
U.freeMemory(addr); // 必須手動釋放!否則記憶體洩漏
}
}
static Unsafe getUnsafe() { /* 同上反射獲取 */ }
}
| 特性 | Heap 陣列 | DirectByteBuffer | Unsafe 離堆 |
|---|---|---|---|
| 最大容量 | 2 GB (byte[]) | MaxDirectMemorySize | 理論無上限 (進程虛擬記憶體) |
| GC 管理 | 自動 | Reference + Cleaner | 完全手動 |
| 存取速度 | 極快 (JIT 優化) | 快 (JNI 開銷) | 最快 (原生指針) |
| 類型安全 | 高 | 中 (View Buffer) | 無 (需自行維護) |
| 適用場景 | 一般業務 | NIO、網路/磁碟零拷貝 | 超大緩存、列式儲存、原生互操作 |
Java 並非無法處理巨量記憶體,關鍵在於選對抽象層級:
• 業務資料 < 2 GB → 堆上陣列/集合
• 網路/磁碟零拷貝 → DirectByteBuffer
• 幾十 GB~TB 熱資料、超低延遲 → 成熟離堆庫 (Chronicle, Netty, Arrow)
• 極致效能、原生互操作 → VarHandle / MemorySegment (JDK 19+ Foreign Function & Memory API)
理解底層機制,架構選型才能游刃有餘。