如何排查java程序的宕機和oom?如何解決宕機和oom?

排查oom

用jmap生成我們的堆空間的快照Heap Dump(堆轉儲文件),來分析我們的內存占用

用可視化工具,例如java中的jhat分析Heap Dump文件 ,它分析完會通過一個瀏覽器打開一個可視化頁面展示分析結果

根據oom的類型來調整我們的內存配置

java.lang.OutOfMemoryError: Java heap space:堆內存不足。java.lang.OutOfMemoryError: Metaspace:元空間(類元數據)不足。java.lang.OutOfMemoryError: Direct buffer memory:直接內存(NIO)不足。java.lang.OutOfMemoryError: Unable to create new native thread:線程數超出限制。java.lang.OutOfMemoryError: GC overhead limit exceeded:GC 頻繁且回收效率低

調整jvm參數

堆內存不足:

-Xms512m -Xmx4g  # 初始堆和最大堆大小
-XX:+UseG1GC      # 使用 G1 垃圾回收器(適合大堆)

metaspace元空間不足:

-XX:MaxMetaspaceSize=512m  # 限制元空間大小
-XX:+CMSClassUnloadingEnabled  # 啟用類卸載(CMS GC)

直接內存不足:

-XX:MaxDirectMemorySize=256m  # 調整直接內存上限


排查宕機(JVM Crash)

1.查看崩潰日志

JVM 崩潰時會生成 hs_err_pid<pid>.log 文件,包含關鍵信息:

崩潰原因:如 SIGSEGV(非法內存訪問)、EXCEPTION_ACCESS_VIOLATION。

堆棧信息:崩潰時的線程堆棧、本地庫調用鏈

2.實時監控工具

jstat:查看 GC 統計信息

jstat -gcutil <pid> 1000  # 每秒打印 GC 情況

jstack:生成線程快照,分析死鎖或線程阻塞

jstack <pid> > thread_dump.txt

Prometheus + Grafana:監控 JVM 內存、GC、線程等指標

啟用 GC 日志

-Xloggc:/path/to/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps

JNI問題是什么?

JNI(Java Native Interface) 是 Java 提供的一種機制,允許 Java 代碼與 C/C++ 等本地(Native)代碼交互。例如,調用操作系統底層 API 或使用高性能計算庫時,可能會用到 JNI。

為什么 JNI 容易出問題?

JNI 是 Java 和本地代碼的“橋梁”,但需要手動管理內存和資源

常見問題包括:

內存泄漏:本地代碼分配的內存未釋放(如 malloc 后未 free)

越界訪問:操作數組時越界(如 GetIntArrayElements 后越界寫數據)

懸空指針:Java 對象被垃圾回收后,本地代碼仍訪問其指針

線程安全問題:本地代碼未正確處理多線程(如未綁定 JNIEnv 到線程)

兼容性問題:編譯的本地庫與操作系統或 JVM 版本不兼容(如 32/64 位不匹配)

JNI 問題導致的典型現象

JVM 崩潰:日志中出現 SIGSEGV(段錯誤)、EXCEPTION_ACCESS_VIOLATION。

內存逐漸耗盡:本地代碼內存泄漏,但 Java 堆內存正常。

應用行為異常:數據損壞、隨機崩潰(如錯誤處理指針)。

如何排查 JNI 問題?

查看崩潰日志:JVM 崩潰時生成的 hs_err_pid<pid>.log 文件,定位崩潰的本地方法和線程

本地代碼調試:

使用 GDB(Linux)或 WinDbg(Windows)調試本地庫。

用 Valgrind(Linux)檢查內存泄漏或越界訪問。

代碼審查:

確保本地代碼正確釋放資源(如 ReleaseArrayElements)。

避免跨線程使用 JNIEnv(每個線程需通過 AttachCurrentThread 獲取)。

簡化復現:隔離 JNI 調用部分,編寫最小測試用例驗證問題


GC日志

什么是GC日志?有什么用?

GC 日志(Garbage Collection Log) 是 JVM 垃圾回收過程的詳細記錄,用于分析內存管理和 GC 性能。

GC 日志的作用

診斷內存問題:

發現頻繁 Full GC(可能內存泄漏)

觀察對象晉升到老年代的速度(過早晉升導致 OOM)

優化 GC 性能:

分析 GC 暫停時間(Stop-The-World)是否影響應用響應

調整堆大小或選擇更合適的 GC 算法(如 G1、ZGC)。

驗證配置效果:

確認 JVM 參數(如 -Xmx、-XX:NewRatio)是否生效。

觀察分代內存分配是否合理


GC 日志包含哪些信息?

時間戳:GC 發生的時間。

GC 類型:GC(Minor GC)、Full GC。

觸發原因:如 Allocation Failure(分配失敗)。

內存變化:各分代(YoungGen、OldGen)回收前后的內存大小。

耗時:user(CPU 用戶態時間)、real(實際暫停時間)

GC 日志的典型分析場景

頻繁 Young GC:

現象:每秒多次 Young GC。

可能原因:新生代太小或短生命周期對象過多。

解決:增大 -Xmn(新生代大小)。

長時間 Full GC:

現象:Full GC 耗時長(如超過 1 秒)。

可能原因:老年代內存不足或內存泄漏。

解決:分析堆轉儲(Heap Dump)檢查大對象


JVM奔潰日志一般會記錄什么信息?

1. 基本信息

時間戳:記錄崩潰發生的具體時間,精確到毫秒甚至更細的粒度,有助于定位問題出現的時間點。

JVM 版本信息:包括 JVM 的供應商、版本號、構建號等,不同版本的 JVM 可能存在不同的特性和已知問題,這些信息對于分析問題很重要。

操作系統信息:如操作系統的名稱、版本、架構(32 位或 64 位)等,因為 JVM 與操作系統的交互可能會影響其穩定性,某些問題可能與特定的操作系統環境相關

2. 崩潰原因信息

錯誤類型:明確指出 JVM 崩潰的錯誤類型,如 OutOfMemoryError(內存溢出錯誤)、StackOverflowError(棧溢出錯誤)等,這些錯誤類型為問題的初步定位提供了方向。

異常信息:如果是由異常導致的崩潰,會詳細記錄異常的類型、消息以及異常發生的調用棧信息。調用棧信息能夠顯示出異常是在哪些方法中被拋出的,幫助開發人員追蹤代碼執行路徑,找到引發問題的具體代碼位置

3. 內存信息

堆內存使用情況:記錄 JVM 堆內存的大小、已使用的堆內存量、剩余的堆內存量等信息。通過這些數據可以判斷是否存在內存泄漏或內存使用不合理的情況。

非堆內存使用情況:對于 JVM 中的非堆內存,如方法區、本地方法棧等,也會有相應的使用情況記錄,有助于全面了解 JVM 的內存占用情況。

垃圾回收信息:包括垃圾回收的次數、不同代(新生代和老年代)的垃圾回收情況、垃圾回收所花費的時間等。垃圾回收如果出現異常,可能導致內存無法及時釋放,進而引發 JVM 崩潰,這些信息可以幫助分析垃圾回收是否正常工作


我們一開始什么都不知道的時候,我怎么知道這個是oom還是宕機

一、觀察現象:快速區分 OOM 和宕機

特征

OOM(內存溢出)

JVM 宕機(Crash)

進程是否存活

進程可能仍在運行(但無法處理請求)

進程直接退出(JVM 崩潰)

日志中的關鍵字

OutOfMemoryError

java.lang.OOM

hs_err_pid<pid>.log

(崩潰日志)

直接表現

拋出異常,可能部分功能不可用,但進程未退出

應用突然消失(如終端打印 Segmentation Fault

是否生成堆轉儲文件

如果配置了 -XX:+HeapDumpOnOutOfMemoryError

,會生成 .hprof

文件

不會生成堆轉儲文件,但會生成崩潰日志文件

二、實操步驟:快速定位問題類型
1. 第一步:檢查進程是否存在

進程還在 → 可能是 OOM 或普通錯誤(如線程阻塞)。

進程消失 → 可能是 JVM 宕機


2. 第二步:查看應用日志

快速搜索日志中的關鍵字:

# 查看最近的應用日志(替換為實際路徑)
tail -n 100 /path/to/application.log | grep -i "outofmemoryerror"

關鍵日志示例

OOM

java.lang.OutOfMemoryError: Java heap space

JVM 宕機

沒有 OOM 錯誤,但進程消失。

可能在系統日志中看到 Segmentation fault(Linux)或 EXCEPTION_ACCESS_VIOLATION(Windows)


3.第三步:檢查崩潰日志(僅宕機)

如果進程消失,JVM 會生成崩潰日志 hs_err_pid<pid>.log

存在 hs_err_pid.log → JVM 宕機(需分析崩潰原因)。

不存在該日志 → 可能是 OOM 或其他問題


4.第四步:驗證 OOM 的堆轉儲文件

如果配置了 -XX:+HeapDumpOnOutOfMemoryError,OOM 時會生成 .hprof 文件

結論:

存在 .hprof 文件 → OOM。

不存在 → 可能是未配置參數,或非堆內存問題(如 Metaspace OOM)


快速總結

進程活著 + 日志有 OOM 錯誤 → OOM

進程消失 + 存在 hs_err_pid.log → JVM 宕機

進程消失 + 無崩潰日志 → 可能是系統殺死(如 OOM Killer)或其他原因


面試問答:如果我們的java程序出現了宕機或oom我們該怎么排查

我們一開始并不知道我們的程序出現錯誤是因為宕機了還是oom?

是因為服務器資源緊張還是java程序配置不合理的原因?

所以我們首先先用top命令去看看服務器整體的內存占用百分比,看看內存是否緊張,我們一般用top命令去查看,但一般都會有現成的監控工具和報警工具,例如普羅米修斯

如果服務器資源不緊張的話,那可能才是java程序本身出了問題

我們要查看java程序是否存活

進程活著 + 日志有 OOM 錯誤 → OOM

進程消失 + 存在 hs_err_pid.log → JVM 宕機

進程消失 + 無崩潰日志 → 可能是系統殺死(如 OOM Killer)或其他原因

啟動Java應用時添加 JVM 參數:

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/dump.hprof

OOM 發生時,JVM 會自動生成堆轉儲文件到指定路徑

如果java程序仍然存活,說明出錯是因為oom,我們內存oom的話我們會生成一個headdump轉儲文件

然后我們查看我們的oom的類型

java.lang.OutOfMemoryError: Java heap space:堆內存不足。java.lang.OutOfMemoryError: Metaspace:元空間(類元數據)不足。java.lang.OutOfMemoryError: Direct buffer memory:直接內存(NIO)不足。java.lang.OutOfMemoryError: Unable to create new native thread:線程數超出限制。java.lang.OutOfMemoryError: GC overhead limit exceeded:GC 頻繁且回收效率低

Metaspace屬于非堆內存,它的OOM可能和堆OOM表現類似,即JVM進程可能仍然存在,但無法繼續加載類,導致應用無法正常運行

我們根據錯誤類型來調整我們的堆內存的空間配置

如果java程序沒有存活,說明就是宕機或者崩潰了

我們的JVM崩潰的時候會生成崩潰日志 hs_err_pid<pid>.log,里面會記錄著我們的jvm的崩潰原因信息,jvm信息,內存信息等,然后我們進行分析

這個都是出問題的時候我們根據文件排查的,但是有時候出了問題我們從文件排查不出來,我們就要用jvm工具來排查oom了

我們可以用jmap來手動生成當前堆內存的轉儲文件headdump,然后用jhat來打開我們的dump文件來分析結果

通過jconsole和普羅米修斯等可視化實時監控工具來查看堆內存,線程,類信息等

jstack分析線程,檢查線程是否阻塞在某個對象分配上(例如等待鎖導致內存無法釋放)

啟用gc日志:

-Xloggc:/path/to/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps

通過可視化gc日志GCViewer來查看gc回收相關信息

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/74965.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/74965.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/74965.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

什么是 OLAP 數據庫?企業如何選擇適合自己的分析工具

引言&#xff1a;為什么企業需要 OLAP 數據庫&#xff1f; 你是否曾經經歷過這樣的場景&#xff1a; 市場部門急需一份用戶行為分析報告&#xff0c;數據團隊告訴你&#xff1a;“數據太大了&#xff0c;報表要跑 4 個小時”&#xff1b;業務負責人在會議中提出一個臨時性分析…

測試:認識Bug

目錄 一、軟件測試的生命周期 二、bug 一、軟件測試的生命周期 軟件測試貫穿于軟件的生命周期。 需求分析&#xff1a; ???度&#xff1a;軟件需求是否合理 技術?度&#xff1a;技術上是否可?&#xff0c;是否還有優化空間 測試?度&#xff1a;是否存在業務邏輯錯誤、…

綜合實驗2

1、sw1和sw2之間互為備份 [sw1]interface Eth-Trunk 0 &#xff08;創建聚合接口&#xff09; [sw1-Eth-Trunk0]trunkport g0/0/1 &#xff08;將物理接口劃入到聚合接口中&#xff09; [sw1-Eth-Trunk0]trunkport g0/0/2 [sw2]interface Eth-Trunk 0 [sw2-Eth-T…

【ArcGIS】ArcGIS10.6徹底卸載和ArcGIS10.2安裝全過程

卸載python3后,解決了ArcGIS與python3沖突問題后,軟件可以正常打開使用了 但是還是出現了問題 用ArcGIS 進行空間分析時,中間操作沒有任何報錯和問題,但是就是沒有運行結果 在別人的軟件上操作一遍可以出現運行結果 關閉確有這個,但真的不是我給它的運行時間不夠,反反復復試…

Django之旅:第五節--Mysql數據庫操作(一)

Django開發操作數據庫更簡單&#xff0c;內部提供了ORM框架 一、安裝第三方模塊 pip install mysqlclient注&#xff1a;最新的django框架需要使用mysqlclient模塊&#xff0c;之前pymysql模塊與django框架有編碼兼容問題。 二、ORM 1、ORM可以幫助我們做兩件事&#xff1a;…

docker部署mongodb數據庫

1、下載 MongoDB 鏡像 使用Docker部署MongoDB 之前&#xff0c;我們需要從 Docker Hub 上下載 MongoDB 鏡像。這里我們下載最新版本的 MongoDB 鏡像&#xff0c;使用以下命令進行下載&#xff1a; docker pull mongo:latest 下載完成后&#xff0c;我們就擁有了最新版本的 Mon…

Enhanced PEC-YOLO:電力施工場景安全裝備檢測的輕量化算法解析

目錄 一、核心概述 二、核心創新點 1. ?C2F_Faster_EMA模塊 2. ?SPPF_CPCA多尺度模塊 3. ?BiFPN頸部網絡

【人工智能】解鎖大模型潛力:Ollama 與 DeepSeek 的分布式推理與集群部署實踐

《Python OpenCV從菜鳥到高手》帶你進入圖像處理與計算機視覺的大門! 解鎖Python編程的無限可能:《奇妙的Python》帶你漫游代碼世界 隨著大語言模型(LLM)的快速發展,其推理能力在自然語言處理、代碼生成等領域展現出巨大潛力。然而,單機部署難以滿足高并發、低延遲的需…

RTMP推流服務器nginx在linux上的編譯部署

RTMP&#xff08;Real-Time Messaging Protocol&#xff09;推流確實需要服務器支持?。RTMP推流服務器的主要功能是接收來自推流客戶端的數據流&#xff0c;對其進行處理和轉發。服務器會根據RTMP協議與客戶端建立連接&#xff0c;處理推流數據&#xff08;如轉碼、錄制等&…

PyQt6實例_批量下載pdf工具_主線程停止線程池

目錄 前置&#xff1a; 代碼&#xff1a; 視頻&#xff1a; 前置&#xff1a; 1 本系列將以 “PyQt6實例_批量下載pdf工具”開頭&#xff0c;放在 【PyQt6實例】 專欄 2 本系列涉及到的PyQt6知識點&#xff1a; 線程池&#xff1a;QThreadPool,QRunnable&#xff1b; 信號與…

Tomcat生產服務器性能優化

試想以下這個情景&#xff1a;你已經開發好了一個程序&#xff0c;這個程序的排版很不錯&#xff0c;而且有著最前沿的功能和其他一些讓你這程序增添不少色彩的元素。可惜的是&#xff0c;程序的性能不怎么地。你也十分清楚&#xff0c;若現在把這款產品退出市場&#xff0c;肯…

正則表達式-筆記

文章目錄 一、正則表達式二、正則表達式的基本語法字符類普通字符非打印字符特殊字符 量詞限定符錨點修飾符&#xff08;標記&#xff09; 三、在 Python 中使用正則表達式簡單搜索提取信息替換文本 參考 從驗證用戶輸入&#xff0c;到從大量文本中提取特定信息&#xff0c;再到…

Qwen-0.5b linux部署

參考鏈接 https://blog.csdn.net/imwaters/article/details/145489543 https://modelscope.cn/models/modelscope/ollama-linux 1. ollama安裝 # 安裝ModelScope工具包&#xff0c;用于下載和管理AI模型 pip install modelscope# 下載Ollama的Linux版本安裝包 # --model 指定…

【深度學習】GAN生成對抗網絡:原理、應用與發展

GAN生成對抗網絡&#xff1a;原理、應用與發展 文章目錄 GAN生成對抗網絡&#xff1a;原理、應用與發展1. 引言2. GAN的基本原理2.1 核心思想2.2 數學表達2.3 訓練過程 3. GAN的主要變體3.1 DCGAN (Deep Convolutional GAN)3.2 CGAN (Conditional GAN)3.3 CycleGAN3.4 StyleGAN…

【AI速讀】CNN圖像處理單元的形式化驗證方法

近年來,卷積神經網絡(CNN)在圖像處理和計算機視覺領域取得了巨大成功,如人臉識別、姿態估計等。然而,基于CNN的圖像處理單元設計復雜,驗證工作面臨巨大挑戰。傳統的仿真驗證方法難以覆蓋其龐大的配置空間,且耗時費力。本文將介紹一種創新的形式化驗證(Formal Verificat…

【新人系列】Golang 入門(八):defer 詳解 - 上

? 個人博客&#xff1a;https://blog.csdn.net/Newin2020?typeblog &#x1f4dd; 專欄地址&#xff1a;https://blog.csdn.net/newin2020/category_12898955.html &#x1f4e3; 專欄定位&#xff1a;為 0 基礎剛入門 Golang 的小伙伴提供詳細的講解&#xff0c;也歡迎大佬們…

鴻蒙開發:了解Canvas繪制

前言 本文基于Api13 系統的組件無法滿足我們的需求&#xff0c;這種情況下就不得不自己自定義組件&#xff0c;除了自定義組合組件&#xff0c;拓展組件&#xff0c;還有一種方式&#xff0c;那就是完全的自繪制組件&#xff0c;這種情況&#xff0c;常見的場景有&#xff0c;比…

【Linux筆記】進程間通信——命名管道

&#x1f525;個人主頁&#x1f525;&#xff1a;孤寂大仙V &#x1f308;收錄專欄&#x1f308;&#xff1a;Linux &#x1f339;往期回顧&#x1f339;&#xff1a;【Linux筆記】進程間通信——匿名管道||進程池 &#x1f516;流水不爭&#xff0c;爭的是滔滔不 一、命名管道…

Spring項目中使用EasyExcel實現Excel 多 Sheet 導入導出功能(完整版)

Excel 多 Sheet 導入導出功能完整實現指南 一、環境依賴 1. Maven 依賴 <!-- EasyExcel --> <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.2</version> </dependency>…

全流程剖析需求開發:打造極致貼合用戶的產品

全流程剖析需求開發&#xff1a;打造極致貼合用戶的產品 一、需求獲取&#xff08;一&#xff09;與用戶溝通1.面談2.問卷調查3.會議討論 &#xff08;二&#xff09;觀察用戶工作&#xff08;三&#xff09;收集現有文檔 二、需求分析&#xff08;一&#xff09;提煉關鍵需求&…