项目问题-OOM内存溢出问题排查方法

OOM内存溢出问题排查方法

在Java项目中,遇到 java.lang.OutOfMemoryError: GC overhead limit exceeded 异常时,通常意味着Java虚拟机(JVM)在进行垃圾回收时耗费了过多的时间,但释放的内存却非常有限。大概率就是因为内存泄漏,下面是一些排查和解决该问题的方法。

1. 手动导出内存快照

1.1. 导出堆内存快照

首先,我们需要获取当前Java进程的PID。可以使用以下命令:

jps -l

输出示例

12345 com.lcj.MainClass

在这个输出中:

  • 12345 是进程的PID(进程ID)。
  • com.lcj.MainClass 是正在运行的Java类的全名。

注意:如果您是在Docker容器中运行Java应用程序,请确保先进入容器,可以使用以下命令:

docker exec -it <container_id> /bin/bash

1.2. 使用 jmap 导出堆内存快照

找到PID后,使用以下命令导出堆内存快照:

jmap -dump:format=b,file=/dump.hprof 12345

这里的 /dump.hprof 是您希望保存堆快照的文件路径。

注意:如果是在Docker中,您需要将生成的快照从容器拷贝到宿主机。可以使用以下命令:

docker cp <container_id>:/dump.hprof /home/dump.hprof

2. 自动导出内存快照

2.1. 设置JVM启动参数

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

例如:

java -Xms750m -Xmx750m -Xmn512m -Xss1024k -XX:MaxPermSize=128m
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/dump.hprof -Dfile.encoding=utf-8 -jar /data/app/test.jar

修改完记得重启,如果是docker环境,记得重建容器

3. 使用 VisualVM 分析堆快照

接下来,我们可以使用工具如 VisualVM 来分析堆快照。

如何查看对象

  1. 打开 VisualVM。
  2. 在左上角的open选项中打开刚刚导出的hprof快照文件。稍等一会它会加载完毕。
  3. 点击Summary旁边的小箭头切换到Objects,可以查看到当前内存快照中所有的对象及数量,点击根据数量count进行排序。
    [
    ]()
  4. 找到排名靠前的几个,查看除了JAVA的那些对象以外,是否有自己定义的业务对象。如果有且数量大,大概率就是有问题的,点击+可以看到持有的类文件名和行数。
    [
    ]()
  5. 此时应该去排查对应代码。检查问题,到这里问题就很容易发现了。

可能的原因

  • 代码长时间未结束:函数内某些逻辑可能一直未结束,持续创建并持有该类型的对象,例如死循环等,且对象数量巨大,长时间持有大量对象引用,导致无法被GC。
  • 静态变量:静态变量可能不断增加,导致内存占用持续上升无法GC。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇