VM 发生 OOM 的 8 种原因、及解决办法

1. 堆空间使用过多

原因

1、Java 堆中无法再分配对象

2、对象被引用,导致对象无法被 GC 回收

3、应用程序过度使用 finalizer。finalizer 对象不能被 GC 立刻回收。

解决方案

1、通过调节JVM参数 -Xmx 增加堆大小

2、优化程序,解决内存泄漏问题

注:

finalize 方法高度依赖 JVM 和 GC,当一个对象被标记后,便会被 JVM 包装成 Finalizer 对象,然后,被 JVM 设置到 Reference 的静态属性 pending 中,Reference 的内部线程则会将这个 pending 放入到构造函数的队列中。

Finalizer 的内部线程则会从队列中取出 Finalizer 对象,并调用其包装的实际对象的 finalize 方法。

所以,finalize 方法需要两个线程来处理他,一个是 ReferenceHandler ,一个是 FinalizerThread。

前者负责将 Finalizer 对象放入到 Reference 队列中,后者负责从队列中取出 Finalizer 对象并调用实际对象的 finalize 方法。

同时,GC 大概也要做 2 件事情,一个是创建 Finalizer 对象,一个是将该对象设置到自己的 pending 属性中。

 pending 英[ˈpendɪŋ]:待定

2. GC 开销过大

原因

1、Java不断的

解决方案

1、通过调节JVM参数 -Xmx 增加堆大小

2、通过调节JVM参数 -XX:-UseGCOverheadLimit 取消 GC 开销限制

3、修复应用程序中的内存泄漏

 

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

原因

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

解决方案

1、通过调节JVM参数 -Xmx 增加堆大小

2、优化代码,不要一次性分配这么大的数组

 

4. Perm gen 空间

gen:情报

原因

Perm gen 空间包含:

1、类的名字、字段、方法

2、与类相关的对象数组和类型数组

3、JIT 编译器优化

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

解决方案

1、通过调节JVM参数 -XX: MaxPermSize 增加 Permgen 大小

 

5. Metaspace

原因

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

解决方案

1、调节参数 -XX: MaxMetaSpaceSize 增加 metaspace 大小

2、增加服务器的内存

3、检查代码,可能是bug引起的

 

6. 发生 stack_trace_with_native_method

原因

1、native method 分配失败

2、查看堆栈信息,最顶层的帧是 native method

解决方案

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

 

7. 杀死进程或子进程

原因

1、内存不足,在可用内存极低的情况下会杀死进程

解决方案

1、将进程迁移到不同的机器上

2、给机器增加更多内存

3、这是由操作系统而非 JVM 触发的。

上一篇:Prepare for Mac App Store Submission--为提交到Mac 应用商店做准备


下一篇:迈达斯midas Gen 2019 2.1 中文汉化安装教程