《JVM如何排查OOM》

目錄

一、什么是OOM?

二、OOM排查的整體思路

三、OOM排查工具大全

四、實戰:不同OOM場景的排查方法

場景1:Java heap space

場景2:Metaspace

場景3:GC overhead limit exceeded

五、高級排查技巧

1. 使用Arthas進行在線診斷

2. 內存泄漏的Breadcrumb策略

3. 壓力測試復現問題

六、預防OOM的最佳實踐

七、真實案例分享

案例1:靜態HashMap導致的內存泄漏

案例2:動態代理類撐爆Metaspace

八、總結

一、什么是OOM?

OOM(Out Of Memory)即內存溢出,是Java開發中最常見的錯誤之一。當JVM內存不足以分配對象空間,并且垃圾收集器也無法回收足夠內存時,就會拋出java.lang.OutOfMemoryError錯誤。

常見的OOM錯誤類型包括:

  1. java.lang.OutOfMemoryError: Java heap space(堆內存不足)

  2. java.lang.OutOfMemoryError: Metaspace(元空間不足)

  3. java.lang.OutOfMemoryError: GC overhead limit exceeded(GC開銷過大)

  4. java.lang.OutOfMemoryError: unable to create new native thread(無法創建新線程)

二、OOM排查的整體思路

確認錯誤類型:首先查看OOM的具體錯誤信息,確定是哪種類型的內存溢出

收集現場信息:在OOM發生時盡可能多地收集系統狀態信息

分析內存使用:通過工具分析內存使用情況

定位問題代碼:找到導致內存泄漏或過度消耗的代碼

修復與驗證:修復問題并驗證解決方案的有效性

三、OOM排查工具大全

1. 命令行工具

jps - 查看Java進程

jps -l

jstat - 監控內存和GC情況

jstat -gcutil <pid> 1000 10 # 每1秒輸出一次,共10次

jmap - 內存分析

jmap -heap <pid> # 查看堆內存配置和使用情況 
jmap -histo <pid> # 查看對象統計信息 
jmap -dump:format=b,file=heap.hprof <pid> # 生成堆轉儲文件

jstack - 線程分析

jstack <pid> > thread.txt

2. 可視化工具

VisualVM:JDK自帶的可視化監控工具

MAT (Memory Analyzer Tool):強大的堆轉儲文件分析工具

JProfiler:商業級性能分析工具

Arthas:阿里開源的Java診斷工具

四、實戰:不同OOM場景的排查方法

場景1:Java heap space

典型表現

java.lang.OutOfMemoryError: Java heap space

排查步驟

  1. 增加JVM參數收集信息:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/dump.hprof
  1. 使用jmap手動生成堆轉儲文件:
jmap -dump:format=b,file=heap.hprof <pid>

使用MAT分析堆轉儲文件:

查找占用內存最大的對象

查看對象的引用鏈

定位到具體的類和代碼行

常見原因:

內存泄漏(對象被意外持有無法回收)

數據量確實過大(需要增加堆內存或優化程序)

場景2:Metaspace

典型表現

java.lang.OutOfMemoryError: Metaspace

排查步驟

查看元空間使用情況:

jstat -gc <pid>

調整JVM參數收集更多信息:

???????-XX:+TraceClassLoading -XX:+TraceClassUnloading

常見原因:

動態生成大量類(如CGLib動態代理)

元空間設置過小(適當增加-XX:MaxMetaspaceSize

類加載器泄漏

場景3:GC overhead limit exceeded

典型表現

java.lang.OutOfMemoryError: GC overhead limit exceeded

排查步驟

查看GC日志:

-Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps

分析GC效率:

關注GC頻率和耗時

觀察每次GC后的內存回收情況

常見原因:

堆內存設置過小

存在內存泄漏導致GC無法有效回收內存

對象存活時間配置不當

五、高級排查技巧

1. 使用Arthas進行在線診斷

# 啟動Arthas 
java -jar arthas-boot.jar 
# 查看JVM內存情況 
dashboard
# 監控方法調用 
monitor -c 5 com.example.demo.Test testMethod 
# 查看對象引用 
vmtool --action getInstances --className java.lang.String --limit 10

2. 內存泄漏的Breadcrumb策略

定期(如每小時)執行jmap -histo:live <pid> > histo_$i.log

對比不同時間點的對象數量變化

找出異常增長的對象類型

3. 壓力測試復現問題

使用JMeter或自定義腳本模擬高并發場景,配合以下JVM參數監控:

-XX:+PrintGCDetails 
-Xloggc:gc.log 
-XX:+HeapDumpOnOutOfMemoryError 
-XX:HeapDumpPath=./oom_dump.hprof

六、預防OOM的最佳實踐

  1. 合理設置JVM參數

    • 根據應用特點設置初始(-Xms)和最大(-Xmx)堆內存
    • 新生代和老年代比例(-XX:NewRatio)
    • 設置元空間大小(-XX:MaxMetaspaceSize)
  2. 代碼層面優化

    • 避免大對象長期存活
    • 及時關閉資源(數據庫連接、文件流等)
    • 謹慎使用靜態集合
    • 合理設計緩存策略
  3. 監控與告警

    • 實施JVM監控(如Prometheus + Grafana)
    • 設置內存使用閾值告警
    • 定期檢查GC日志
  4. 定期演練

    • 模擬OOM場景進行演練
    • 驗證監控告警的有效性
    • 測試團隊對OOM的響應流程

七、真實案例分享

案例1:靜態HashMap導致的內存泄漏

現象:應用運行幾天后必現OOM

排查

  1. 堆轉儲分析顯示HashMap占用了80%內存
  2. 追溯發現是全局靜態HashMap緩存用戶數據但從未清理
  3. 隨著用戶量增加,HashMap不斷增長

解決

  1. 改用WeakHashMap或帶過期策略的緩存
  2. 實現定期清理機制

案例2:動態代理類撐爆Metaspace

現象:高并發下頻繁出現Metaspace OOM

排查

  1. 發現Metaspace使用量持續增長
  2. 分析類加載日志發現大量動態代理類
  3. 確認是框架為每個請求生成新代理類

解決

  1. 增加Metaspace大小
  2. 優化框架配置,啟用代理類緩存

八、總結

OOM排查是Java開發者必備的技能,需要掌握:

  • 理解JVM內存模型和各區域作用
  • 熟練使用各種診斷工具
  • 建立系統化的排查思路
  • 積累常見場景的解決經驗
  • 重視預防和監控,而非僅事后補救

記住:好的開發者不是不會遇到OOM,而是能夠快速定位和解決OOM問題。希望本文能幫助你在遇到OOM時不再恐慌,而是有條不紊地解決問題。

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

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

相關文章

ubuntu22.04 安裝Docker

一、更新系統包索引sudo apt update && sudo apt upgrade -y二、安裝必要依賴安裝 curl、gnupg等工具&#xff0c;用于添加 Docker 官方 GPG 密鑰和倉庫&#xff1a;sudo apt install -y ca-certificates curl gnupg三、添加 Docker 官方 GPG 密鑰sudo install -m 0755…

高低壓隔離器的技術演進與行業賦能

電力電子系統的安全架構與效率升級&#xff0c;始終依賴高低壓電路間的可靠隔離。高低壓隔離器作為能量傳輸與信號控制的核心媒介&#xff0c;通過持續迭代的絕緣技術與結構創新&#xff0c;為新能源裝備、工業驅動系統提供底層安全屏障。其阻斷電位差傳導、抑制電磁干擾的能力…

嵌入式 - ARM5

一、led點燈代碼優化1. 配置寄存器volatile1.??禁止優化??不對該變量的讀寫操作進行任何優化&#xff08;如刪除“冗余”讀取或延遲寫入&#xff09;。2.??強制內存訪問??每次訪問該變量時&#xff0c;必須直接從內存&#xff08;或硬件寄存器&#xff09;中讀取或寫入…

SSH登錄管理

兩種配置方法-密碼 -密鑰&#xff08;免密&#xff09;ansible 默認 rhel9 禁止 root 用密碼登陸&#xff0c;不禁止用密鑰登陸 ---修改方式----vim /etc/ssh/sshd_config 修改此文件#PermitRootLogin prohibit-passwordPermitRootLogin yes 改為允許systemctl res…

遠程連接--向日葵

下載安裝卸載 向日葵語言設置 點擊下面的圖標,點擊"設置": 問題解決 向日葵被連接之后自動黑屏 取消下面的勾選框: 向日葵連接之后黑屏 檢查系統的協議: echo $XDG_SESSION_TYPE 如果是: wayland 需要切換為x11. 設置永久默認使用 X11: sudo vi /etc/gdm3/custom…

Liunx執行source /etc/profile 報錯, -bash: HISTTIMEFORMAT: readonly variable

今天在配置java環境變量時&#xff0c;執行source /etc/profile報錯&#xff0c;系統是統信OS&#xff0c;花了好長時間才解決&#xff0c;在這記錄一下&#xff0c;希望能幫助到大家問題截圖提示HISTTIMEFORMAT和PROMPT_COMMAND變量時只讀變量&#xff0c;不能設置屬性值解決辦…

什么是達林頓管?

簡單來說&#xff0c;達林頓管是一個“電流放大器中的大力士”。它的核心目的是用非常小的輸入電流&#xff08;基極電流&#xff09;去控制一個非常大的輸出電流&#xff08;集電極電流&#xff09;。達林頓管是由兩個三極管串聯而成&#xff0c;放大倍數是兩個三極管的放大倍…

嵌入式Linux學習_rk3588移植無線網卡驅動

記錄移植無線網卡驅動遇到的各種問題&#xff1a; 從官網上下載8821的驅動源碼復制一份上面的CONFIG_PLATFORM_ARM_RK2818&#xff0c;改成3588&#xff0c;然后選項改成y&#xff0c;并把autodetect關掉。 找到CONFIG_PLATFORM_ARM_RK2818&#xff0c;復制一份&#xff0c;改成…

MCP專題五、MCP 的未來趨勢與展望

MCP專題五:MCP 的未來趨勢與展望 5.1 引言 本專題前四章我們系統性地學習了 MCP(Model Context Protocol)的 發展背景、核心機制、Python 實戰方法以及典型應用場景。可以看到,MCP 并不僅僅是一個技術標準,它更像是 大模型與外部世界溝通的橋梁,推動了 AI 應用從“實驗…

C++ Dijkstra堆優化算法

時間復雜度為&#xff1a;O((nm)logn)算法特點&#xff1a;非負邊權、單源最短路、頂點數、邊數<1000000&#xff0c;數據結構前置&#xff1a;領接表、哈希表、二叉堆算法&#xff1a;第一步&#xff0c;建圖&#xff0c;任何算法我們都要去思考&#xff0c;用什么數據結構…

網頁設計作業02

<!DOCTYPE html> <html> <head><meta charset"utf-8"/><title>網頁設計作業</title> </head> <body><h2>問卷調查</h2><p><strong>1、你是通過什么途徑來到綠葉學習網的&#xff1f;</s…

每日算法題推送-->今日專題——雙指針法

題目1&#xff1a;https://leetcode.cn/problems/move-zeroes 小編剛看到這道題的時候&#xff0c;想到的第一個方法就是建立一個與原數組等大的新的數組&#xff0c;然后遍歷原數組&#xff0c;如果遇到元素值不為0的元素&#xff0c;就將這個元素放到新數組中&#xff0c;直到…

告別單次對話:上下文工程如何重塑AI應用架構

1. 前言人工智能應用開發領域正在經歷一場靜悄悄的變革。去年此時&#xff0c;提示工程&#xff08;Prompt Engineering&#xff09;還是各大技術論壇的熱門話題&#xff0c;開發者們熱衷于分享各種精心設計的提示詞模板&#xff0c;試圖通過單次交互獲得理想的大模型輸出。然而…

PM2 管理后端(設置項目自啟動)

查看pm2管理pm2 list ┌────┬──────────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──…

CCN中商再獲三項知識產權,為數字化服務添動能

上海中商網絡股份有限公司&#xff08;CCN中商&#xff09;依托持續的研發投入與深厚的技術積淀&#xff0c;在知識產權領域再獲重要突破——成功收獲三項知識產權&#xff0c;囊括實用新型專利《一種3D霓彩智感雙條光柱印刷用全自動生產線》、發明專利《一種一物一碼關聯系統及…

使用LTspice仿真一個異步BUCK電路

確定異步BUCK的規格 輸入電壓&#xff08;Vin&#xff09;&#xff1a;12V 輸出電壓&#xff08;Vout&#xff09;&#xff1a;6V 最大輸出電流&#xff08;Iout&#xff09;&#xff1a;3A 開關頻率&#xff08;fsw&#xff09;&#xff1a;400kHz 輸出電壓紋波&#xff08;Δ…

R語言對excel中多個sheet子表批量進行地理探測器計算

## 基本設置 ## 1) 設定你的工作目錄&#xff08;保持你的原路徑不變&#xff09; setwd("D:/*****/*****/******")## 2) 文件名&#xff08;與xlsx實際名字保持一致&#xff09; xlsx_file <- "驅動因素&#xff08;中低收入&#xff09;.xlsx"## 依…

C++ JSON 數據庫:jsoncpp

jsoncpp1. JSON數據1.1 JSON 的基本語法規則1. 基礎語法要求兩種核心數據結構JSON 與其他數據格式的對比1.2 JSON 的典型應用場景1.3 JSON 解析與生成工具2. 編程語言庫&#xff08;解析/生成&#xff09;1.4 常見錯誤與注意事項2. jsoncpp2.1 基本用法1. 安裝與集成2. 核心類與…

《蒼穹外賣》項目日記_Day9

前言&#xff1a; 上午就把今天任務完成了&#xff0c;就繼續往后學了一些知識&#xff0c;晚上寫下筆記總結一下。 今日完成任務&#xff1a; 調用百度地圖開放平臺&#xff0c;優化用戶下單業務學習SpringTask&#xff0c;定時處理超時、派送中訂單學習WebSocket&#xff0c;…

人工智能學習:Transformer結構中的編碼器層(Encoder Layer)

Transformer結構中的編碼器層(Encoder Layer) 一、編碼器層介紹 概念 編碼器層(Encoder Layer)是Transformer編碼器的基本構建單元,它重復堆疊形成整個編碼器,負責逐步提取輸入序列的特征。每個編碼器層由兩個核心子層組成: 多頭自注意力機制(Multi-Head Self-Attentio…