请教 Java OOM 及 JVM 相关的问题

superhot · 2024-10-17 17:22:42 · 225 次点击
## 背景

1. AWS EC2 `t3.medium` 实例,Amazon Linux 2 系统,4GB 内存。
2. Java 启动时 Heap 的配置为 `-Xmx2847m`,大概是给其他服务留 1G 左右内存,其余全部分配给 JVM 。
3. 结合日志和后台监控发现频繁出现 OOM 导致 Tomcat 重启的问题。

## 问题

1. 现在每个实例的平均内存使用率在 93% 左右,此现象是否正常?
2. 保持当前 EC2 实例配置不变的情况下,给 JVM Heap 分配多大内存比较合适?有什么可以拿来当作判断的依据吗?
3. 除了 Heap 之外,JVM 还有 Metaspace 、CodeCache 、DirectByteBuffers 等等,这些 Heap 之外的部分可能吃掉多少内存?有什么可以拿来当作判断的依据吗?
4. 如何分析 OOM 可能的情况?`/usr/share/tomcat` 目录下有个 `hs_err_pid` 前缀的日志文件,似乎在 OOM 时会输出相关错误信息,但根本看不懂……

一年后端经验的 CRUD Boy 没系统学过 Java ,不了解 JVM ,突然让去解决 OOM 的问题,实在懵逼,不知从何下手,请各位 Java 大佬们给点建议,救救本菜,谢谢大家!
举报· 225 次点击
登录 注册 站外分享
16 条回复  
yuemingming 初学 2024-10-17 19:57:24
「结合日志和后台监控发现频繁出现 OOM 导致 Tomcat 重启的问题。」
贴一下后台异常重启的日志呢。
正常来说一个系统平稳运行是不应该 OOM 的。即使你的堆内存比较小,但是只要系统使用了内存之后正常释放,也是可以通过垃圾回收释放这些内存的。就是可能垃圾回收的频率比较高。
如果频繁 OOM 的话,两种情况,一种是正常情况,处理请求的过程中,需要大量的内存,但是所有可回收的都已经回收了,还是不够。另一种就是代码写的有问题,该回收的没回收。
堆内存配置看着比较合理,正常来说留一个 G ,一部分操作系统需要,一部分 JVM 的一些其他机制也需要堆外内存。比如线程堆栈。
sagaxu 初学 2024-10-17 18:45:59
-Xmx 调小一点试试,比如 2000m

总内存只有 4G ,设置-Xmx2847m 一定会 OOM
paranoiagu 小成 2024-10-17 18:28:34
给太高了吧。
jorneyr 小成 2024-10-17 18:23:00
例如代码里把 1G 文件全部一次性读入内存,先分析代码的原因。
xiwolaisi 小成 2024-10-17 18:08:39
jvm dump 分析网站,我自己懒得跑 MAT 的时候就用这个👻
https://heaphero.io/heap-index.jsp#header
ZZ74 小成 2024-10-17 17:54:27
现在每个实例的平均内存使用率在 93% 左右,此现象是否正常? 正常。
参考这个帖子 https://www.fex.com/t/1078482?p=1#reply22 贴出 hs_err_pid 内容。贴给 AI 都会给你分析。
wenning 初学 2024-10-17 17:49:13
springboot 的话加上 actuator, 配合 prometheus, grafana 看看 jvm 相关的使用情况; 90%的占用肯定不正常了, 相当于比较吃紧了, 如果来点压力就挂了, 再留一点内存给系统, 否则内存满了直接会被系统 kill
defunct9 初学 2024-10-17 17:38:09
升级 ec2 ,给 8G 内存
Geekerstar 小成 2024-10-17 17:34:29
把这个 hs_err_pid 日志发出来,我最近也遇到 OOM 了,能帮忙排查下。可以看我最近发的一个帖子。
INCerry 小成 2024-10-17 17:33:17
什么版本的 Java ?如果版本高只想解决问题,那先:

-XX:+UnlockExperimentalVMOptions
-XX:+UseShenandoahGC
-XX:ShenandoahGCHeuristics=compact
12下一页
返回顶部