一文了解 OutOfMemory 及解决方案

一文了解 OutOfMemory 及解决方案

1. Java 堆空间

发生频率

5颗星

造成原因

  1. 无法在 Java 堆中分配对象
  2. 吞吐量增加
  3. 应用程序无意中保存了对象引用,对象无法被 GC 回收
  4. 应用程序过度使用 finalizer。finalizer 对象不能被 GC 立刻回收。finalizer 由结束队列服务的守护线程调用,有时 finalizer 线程的处理能力无法跟上结束队列的增长

解决方案

单位对应:GB -> G, g;MB -> M, m;KB -> K, k

  1. 使用 -Xmx 增加堆大小
  2. 修复应用程序中的内存泄漏

2. GC 开销超过限制

发生频率

5颗星

造成原因

  1. Java 进程98%的时间在进行垃圾回收,恢复了不到2%的堆空间,最后连续5个(编译时常量)垃圾回收一直如此。

解决方案

  1. 使用 -Xmx 增加堆大小
  2. 使用 -XX:-UseGCOverheadLimit 取消 GC 开销限制
  3. 修复应用程序中的内存泄漏

3. 请求的数组大小超过虚拟机限制

发生频率

2颗星

造成原因

  1. 应用程序试图分配一个超过堆大小的数组

解决方案

  1. 使用 -Xmx 增加堆大小
  2. 修复应用程序中分配巨大数组的 bug

4. Permgen 空间

发生频率

3颗星

造成原因

Permgen 空间包含:

  • 类的名字、字段、方法
  • 与类相关的对象数组和类型数组
  • JIT 编译器优化

当 Permgen 空间用尽时,将抛出异常。

解决方案

  1. 使用 -XX: MaxPermSize 增加 Permgen 大小
  2. 不重启应用部署应用程序可能会导致此问题。重启 JVM 解决

5. Metaspace

发生频率

3颗星

造成原因

  1. 从 Java 8 开始 Permgen 改成了 Metaspace,在本机内存中分配 class 元数据(称为 metaspace)。如果 metaspace 耗尽,则抛出异常

解决方案

  1. 通过命令行设置 -XX: MaxMetaSpaceSize 增加 metaspace 大小
  2. 取消 -XX: maxmetsspacedize
  3. 减小 Java 堆大小,为 MetaSpace 提供更多的可用空间
  4. 为服务器分配更多的内存
  5. 可能是应用程序 bug,修复 bug

6. 无法新建本机线程

发生频率

5颗星

造成原因

  1. 内存不足,无法创建新线程。由于线程在本机内存中创建,报告这个错误表明本机内存空间不足

解决方案

  1. 为机器分配更多的内存

  2. 减少 Java 堆空间

  3. 修复应用程序中的线程泄漏。

  4. 增加操作系统级别的限制

    • ulimit -a
    • 用户进程数增大 (-u) 1800
  5. 使用 -Xss 减小线程堆栈大小

7. 杀死进程或子进程

发生频率

1颗星

造成原因

  1. 内核任务:内存不足结束器,在可用内存极低的情况下会杀死进程

解决方案

  1. 将进程迁移到不同的机器上
  2. 给机器增加更多内存

与其他 OOM 错误不同,这是由操作系统而非 JVM 触发的。

8. 发生 stack_trace_with_native_method

发生频率

1颗星

造成原因

  1. 本机方法(native method)分配失败
  2. 打印的堆栈跟踪信息,最顶层的帧是本机方法

解决方案

  1. 使用操作系统本地工具进行诊断

 上一篇
2018年面试过阿里、网易、海康的大数据总结的面试题 2018年面试过阿里、网易、海康的大数据总结的面试题
2018年面试过阿里、网易、海康的大数据总结的面试题(1)spark运行流程、源码架构(2)Hbase主键设计、hbase为啥比mysql快、为什么项目选用hbase(3)Hbase读写流程,数据compact流程HBase写数据流程1,C
2019-02-06
下一篇 
定时器的几种实现方式 定时器的几种实现方式
定时器的几种实现方式1 前言在开始正题之前,先闲聊几句。有人说,计算机科学这个学科,软件方向研究到头就是数学,硬件方向研究到头就是物理,最轻松的是中间这批使用者,可以不太懂物理,不太懂数学,依旧可以使用计算机作为自己谋生的工具。这个规律具有
2019-01-30
  目录