概述

有时Java服务端上线后,运行一段时间后就会出现OOM 问题,这样问题是非常严重的。
那要怎样排查?怎样解决?

工具安装:

为什么会要安装工具?这是因为我们现在按照的open jdk 是默认没有安装jmap,jstatck,需要自行安装。
以 Centos7 为例 介绍安装过程
先使用 java -version 版本 号

OpenJDK Runtime Environment (build 1.8.0_322-b06)

查询 Jmap 与java 当前版本匹配的版本

yum whatprovides '*/jmap'

找到相应的版本安装

yum install java-1.8.0-openjdk-devel-1.8.0.322.b06-1.el7_9.x86_64

到此这样工具就完成了。

回到正轨,问题出现怎样排查问题
查看服务的进程是否存在

ps -ef | grep 服务名 ps -aux | grep 服务名

查看服务的日志

cat -n xxx_log |grep "OutOfMemoryError"
「java.lang.OutOfMemoryError GC overhead limit exceeded oracle

官方给出的解释如下:
大概意思就是说,JVM花费了98%的时间进行垃圾回收,而只得到2%可用的内存,频繁的进行内存回收(最起码已经进行了5次连续的垃圾回收),JVM就会曝出ava.lang.OutOfMemoryError: GC overhead limit exceeded错误。

查看堆内存占用概况

jmap -heap 进程号

查看堆中对象的统计信息

jmap -histo 进程号 | head -n 100

查看GC统计信息

jstat -gcutil 进程号
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.00 0.00 100.00 99.94 90.56 87.86 875 9.307 3223 5313.139 5322.446
S0:幸存1区当前使用比例
S1:幸存2区当前使用比例
E:Eden Space(伊甸园)区使用比例
O:Old Gen(老年代)使用比例
M:元数据区使用比例
CCS:压缩使用比例
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间

生产对堆快照Heap dump

jmap -dump:format=b,file=/tmp/进程号_jmap_dump.hprof 进程号

分析生成的堆快照

使用 Eclipse Memory Analyzer 工具。下载地址:www.eclipse.org/mat/download

排查线上环境 OOM 问题_垃圾回收


排查线上环境 OOM 问题_eclipse_02


这样就能看到那个对象占用内存情况,这样就可以根据代码查看了。