当JVM内存严重不足时,就会抛出java.lang.OutOfMemoryError异常。
本文总结了常见的OOM异常的原因及解决办法。
image.png

Java heap space

  • 问题描述

当堆内存(Heap Space)没有足够空间存放新创建的对象时,就会抛出java.lang.OutOfMemoryError: Java heap space错误

  • 原因分析

Java heap space错误产生的常见原因可以分为以下几类

  1. 请求创建一个超大对象,通常是一个大数组。
  2. 超出预期的访问量/数据量,通常是上游系统请求流量飙升,常见于各类促销/秒杀活动,可以结合业务流量指标排查是否有尖状峰值。
  3. 过度使用终结器(Finalizer),导致对象没有立即被GC。
  4. 递归没有正常结束,导致无限递归
  5. 内存泄漏(MemoryLeak),大量对象引用没有释放,JVM无法对其自动回收
  • 解决方案
    1. 针对大部分情况,通常只需要通过-Xmx参数调高JVM堆内存空间即可
    2. 如果是超大对象,可以检查其合理性,比如是否一次性查询了数据库全部结果,而没有做结果数限制。
    3. 如果是业务峰值压力,可以考虑添加机器资源,或者做限流降级。
    4. 如果是内存泄漏或无限递归,则需要排除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(阿尔萨斯)

https://github.com/alibaba/arthas