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

Java 記憶體溢位示例:Heap OOM 與 StackOverflow

     編輯:Java 相關知識

Java 兩大經典記憶體錯誤重現與分析

Java 執行期常見的兩種記憶體錯誤為 Heap Space 不足(`OutOfMemoryError: Java heap space`)與 堆疊溢位(`StackOverflowError`)。本文提供最小重現程式碼並說明原因與對策。

1. Heap Space 溢位(Java Heap Space)

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` 設定上限。

對策:

  • 檢查記憶體洩漏(如靜態集合持有大量物件、未關閉資源)。
  • 調大 Heap:`-Xmx2g`(視機器實體記憶體而定)。
  • 使用弱參考(`WeakReference`)或定期清理快取。
  • 啟用 GC 日誌分析:`-XX:+PrintGCDetails -Xloggc:gc.log`。

2. 堆疊溢位(StackOverflowError)

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)。

對策:

  • 修正遞迴邏輯,確保有基底條件終止。
  • 改用迴圈替代遞迴(尾遞迴優化在 Java 不保證)。
  • 調大堆疊:`-Xss2m`(謹慎使用,會減少可建立執行緒數)。

常見誤區

錯誤類型發生區域典型原因JVM 參數
OutOfMemoryError: Java heap spaceHeap物件過多/洩漏-Xmx
OutOfMemoryError: MetaspaceMetaspace類載入過多/類洩漏-XX:MaxMetaspaceSize
StackOverflowErrorThread Stack遞迴過深/死循環呼叫-Xss
OutOfMemoryError: Unable to create native threadOS Native執行緒過多/堆疊過大-Xss, ulimit -u

排查工具

  • jmap -histo:live pid:查看 Heap 物件統計。
  • jstack pid:查看執行緒堆疊,定位遞迴位置。
  • VisualVM / JConsole / Arthas:圖形化監控與分析。
  • Eclipse MAT:離線分析 Heap Dump(`-XX:+HeapDumpOnOutOfMemoryError`)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved