簡體   English   中英

在 Web 服務器線程中獲取 OutOfMemoryError 時,Spring 啟動請求掛起

[英]Spring boot requests hang when getting OutOfMemoryError in web server threads

由於某些錯誤,我的應用程序消耗了太多內存並且堆空間已用完。

但是,不是請求失敗,而是無限掛起,並且僅在控制台中出現以下錯誤:

*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message can't create name string at JPLISAgent.c line: 826

Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "http-nio-8090-ClientPoller"

Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "Catalina-utility-2"

Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "Catalina-utility-1"

為什么請求掛起而不失敗? 唯一的解決方案(除了不超出內存之外)是終止服務嗎? (它在容器中運行,所以它會重新啟動)

我殺死服務的代碼:

static class GlobalThreadExceptionHandler implements UncaughtExceptionHandler {
    @Override
    public void uncaughtException(Thread thread, Throwable throwable) {
        logger.error(String.format("Caught unhandled exception in thread %s", thread), throwable);
        Runtime.getRuntime().halt(137);
    }
}

public static void main(String[] args) {
  Thread.setDefaultUncaughtExceptionHandler(new GlobalThreadExceptionHandler());
  ...
}

System.exit()也掛了)

我正在使用 Java 11 和 Spring Boot 版本 2.1.6

這是 Java 垃圾收集器嘗試釋放內存時應用程序的暫停時間或延遲時間。 但似乎垃圾收集器也無法在內存已滿時運行。 所以應用程序被掛起。

有許多新的垃圾收集器,如 zgc、shenandoah,它們可以與應用程序並行運行以持續釋放內存,但我不知道它們在這里是否適用。

如果您正在使用 docker 容器,您可以檢查“docker stats”以檢查您的 contains 何時使用和釋放內存。 如果您的系統有足夠的內存,您可以相應地增加/設置容器的 MAX_HEAP 大小變量。 您也可以相應地移動/縮放其他容器,以便此容器獲得更多資源。

我有一個類似的問題。 我已經在使用 zgc 和/或 shenandoah 並沒有太大幫助。

我的問題是我實際上正在將大量數據加載到內存中,而容器最終用完了。

我能夠使用 Jprofiler ( https://www.ej-technologies.com/products/jprofiler/overview.html ) 找到問題並優化代碼。 有了它,我能夠准確地檢測到哪個類正在消耗內存。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM