当JVM内存严重不足时,就会抛出java.lang.OutOfMemoryError异常。
本文总结了常见的OOM异常的原因及解决办法。
Java heap space
- 问题描述
当堆内存(Heap Space)没有足够空间存放新创建的对象时,就会抛出java.lang.OutOfMemoryError: Java heap space错误
- 原因分析
Java heap space错误产生的常见原因可以分为以下几类
- 请求创建一个超大对象,通常是一个大数组。
- 超出预期的访问量/数据量,通常是上游系统请求流量飙升,常见于各类促销/秒杀活动,可以结合业务流量指标排查是否有尖状峰值。
- 过度使用终结器(Finalizer),导致对象没有立即被GC。
- 递归没有正常结束,导致无限递归
- 内存泄漏(MemoryLeak),大量对象引用没有释放,JVM无法对其自动回收
- 解决方案
- 针对大部分情况,通常只需要通过-Xmx参数调高JVM堆内存空间即可。
- 如果是超大对象,可以检查其合理性,比如是否一次性查询了数据库全部结果,而没有做结果数限制。
- 如果是业务峰值压力,可以考虑添加机器资源,或者做限流降级。
- 如果是内存泄漏或无限递归,则需要排除bug
GC overhead limit exceeded
问题描述
- 当Java进程花费98%以上的时间执行GC,但只恢复了不到2%的内存,且该动作连续重复了5次,就会抛出java.lang.OutOfMemoryError: GC overhead limit exceeded错误。
- 简单地说,就是应用程序已经基本耗尽了所有可用内存,GC也无法回收。
解决方案
此类问题的原因与解决方案跟Javaheapspace非常类似,可以参考其解决方案
推荐工具&产品
- 阿里云APM产品,支持OOM异常关键字告警
https://help.aliyun.com/document_detail/42966.html?spm=a2c4g.11174283.6.685.d69b668cuztvff
- 阿里Java在线诊断工具Arthas(阿尔萨斯)