Skip to content

Commit

Permalink
Create 2023-12-08-一招定位JAVA_OOM中的大对象.md
Browse files Browse the repository at this point in the history
  • Loading branch information
MisterChangRay authored Dec 19, 2023
1 parent fb18a5f commit 6f44a3f
Showing 1 changed file with 49 additions and 0 deletions.
49 changes: 49 additions & 0 deletions _posts/2023-12-08-一招定位JAVA_OOM中的大对象.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
layout: post
title: "一招定位JAVA_OOM中的大对象"
date: 2023-12-18 13:29:20 +0800
categories:
- 杂项
tags:
- java内存泄漏
- oom堆镜像分析
- 溢出代码定位
---


java开发中,最令人憎恨的便是跑着跑着出现OOM

内存溢出对于新手来说最为头痛,隐蔽且难以排查。

对于正常应用来说500MB内存足够了,出现OOM一般是内存中持有太多不可释放对象,主要排查以下几点:
1. list 或者 MAP 装太多,而且不释放,较多存在于静态引用中
2. 数据库或者读文件一次读取太多了,比如20W行数据库记录一下加载到内存中, 较多存在于没有limit参数,或者统计sql
3. threadlocal,StringBuffer, ByteBuffer等



内存泄漏的一般伴随着如下现象:
- OOM伴随着疯狂的fullgc. 一般1-3S一次
- cpu的异常增高,100%, 200%, 此时主要是JVM疯狂做无效full gc 导致
- 服务假死,不可访问,重启服务后恢复正常。由于GC造成的`Stopwrold`导致

那么这种问题如何排查呢,这里介绍一个通用的流程:
1. oom后导出内存镜像,使用命令为`jmap -dump:format=b,file=文件名.hprof <进程ID>`
2. 使用`JAVA_Memory_Analyzer_Tool` 进行分析。

工具分析操作步骤如下:

1. 打开内存镜像文件`File->open file`
2. 点击按钮,分析对象
![image](https://github.com/MisterChangRay/misterchangray.github.io/assets/16421384/266b81f7-06d7-4987-9d95-5e9ae1eb50d3)
3. 点击按包名分组排序,即可
<img width="755" alt="image" src="https://github.com/MisterChangRay/misterchangray.github.io/assets/16421384/ff3ee3b5-1e34-458d-881f-08d5348cb59e">

图片中,`Objects`代表对象在内存中的数量。

上面的操作将会将内存的所有对象按照包名分组并排好序,
接着只需去查看自己业务包下面哪个对象最多,再分析其存在是否合理,基本就能排查出问题所在了。

附:
oom一般是出现问题后手动导出,但是更为推荐的是在java启动中增加参数,出现oom时JVM将会自动到处镜像。方便排查。

0 comments on commit 6f44a3f

Please sign in to comment.