JavaOOM
Contents
💠
-
- 1.1. 简单案例
- 1.2. Heap space OOM
- 1.3. Metaspace OOM
- 1.4. Compressed Class Space OOM
- 1.5. Direct Memory OOM
- 1.6. GC overhead limit exceeded
💠 2024-11-18 14:31:55
OOM
注意OOM并不代表Java进程一定会退出,如果导致OOM的地方能被catch,且泄漏点能随着这次任务的终止而可回收的话,JVM将继续正常运行。
Why JVM can recovery from OOM Java heap space by itself
简单案例
例如
|
|
又或者常见的SpringMVC服务
|
|
注意 org.springframework.web.servlet.DispatcherServlet
中的 doDispatch
catch了Error也包装成了Exception,方便统一异常处理器。
这只会导致Tomcat的NIO线程终止了这次请求,局部变量 data 就可以回收掉了,整个服务仍正常进行,只是在快要OOM时高频的GC影响了系统的吞吐量而已。
|
|
Heap space OOM
异常信息:
java.lang.OutOfMemoryError: Java heap space java.lang.OutOfMemoryError: Requested array size exceeds VM limit
Error java.lang.OutOfMemoryError: GC overhead limit exceeded常见于内存缓慢泄漏,GC成本越来越高时
Metaspace OOM
一次Metaspace OutOfMemoryError问题排查记录很多GeneratedMethodAccessor类
原理理解比较复杂,但定位和解决问题会比较简单,经常会出问题的几个点有 Orika 的 classMap、JSON 的 ASMSerializer、Groovy动态加载类等,基本都集中在 反射、Javasisit字节码增强、CGLIB动态代理、OSGi自定义类加载器等技术点上
https://heapdump.cn/article/1924890 https://heapdump.cn/article/54786?from=pc https://heapdump.cn/article/2152817
-XX:+TraceClassLoading -XX:+TraceClassUnloading -verbose:class
https://developer.aliyun.com/article/780535
https://javakk.com/805.html https://www.dongcb.com/818.html
https://juejin.cn/post/7114516283290288158
Compressed Class Space OOM
Direct Memory OOM
GC overhead limit exceeded
Error java.lang.OutOfMemoryError: GC overhead limit exceeded
分析
重点是保存现场,获取到问题时间内多维度的信息辅助快速定位,首要是 dump文件 其次是 jstack历史 gc日志 应用日志 监控系统上问题时间段的指标变化情况 等等。
由JDK bug引发的线上OOM Speeding up Java heap dumps with GNU Debugger
但是实测更慢,可能和环境有关吧 maybe
- jmap
- jcmd 1 GC.heap_dump /tmp/docker.hprof
通常使用 jmap或jcmd dump到文件,但是如果JVM已经发生OOM且进程占用CPU很高的情况下jmap会很慢甚至失败(例如attach失败)。 此时可以使用gdb先dump下core,再转为hprof文件。
- ulimit -c unlimited
- gcore pid
core文件可能会很大,800M堆dump出了7G的文件
- jmap -dump:format=b,file=heap.hprof /path/to/java core.${pid}
该过程是单线程的,会很慢
Author Kuangcp
LastMod 2024-03-06