Java 執行期常見的兩種記憶體錯誤為 Heap Space 不足(`OutOfMemoryError: Java heap space`)與 堆疊溢位(`StackOverflowError`)。本文提供最小重現程式碼並說明原因與對策。
import java.util.ArrayList;
import java.util.List;
public class HeapOOM {
public static void main(String[] args) {
List<Object> list = new ArrayList<>();
while (true) {
list.add(new HeapOOM()); // 不斷新增物件至 List,GC 無法回收
}
}
}
錯誤輸出:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
原因:物件持續累積在 Heap 中且被強參考持有,超過 `-Xmx` 設定上限。
對策:
public class StackOverflow {
public static void main(String[] args) {
new StackOverflow().recursive();
}
public void recursive() {
recursive(); // 無終止條件的無限遞迴
}
}
錯誤輸出:
Exception in thread "main" java.lang.StackOverflowError
原因:每次方法呼叫在執行緒堆疊分配幀,無限遞迴耗盡預設堆疊大小(通常 512KB~1MB)。
對策:
| 錯誤類型 | 發生區域 | 典型原因 | JVM 參數 |
|---|---|---|---|
| OutOfMemoryError: Java heap space | Heap | 物件過多/洩漏 | -Xmx |
| OutOfMemoryError: Metaspace | Metaspace | 類載入過多/類洩漏 | -XX:MaxMetaspaceSize |
| StackOverflowError | Thread Stack | 遞迴過深/死循環呼叫 | -Xss |
| OutOfMemoryError: Unable to create native thread | OS Native | 執行緒過多/堆疊過大 | -Xss, ulimit -u |