Jvm内存溢出的几种情况

1.Java堆空间

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

解决方案:
* 使用 -Xmx 增加堆大小
* 修复应用程序中的内存泄漏

2.GC开销超过限制

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

解决方案:
* 使用 -Xmx 增加堆大小
* 使用 -XX:UseGCOverheadLimit取消GC开销限制
* 修复应用程序中的内存泄漏

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

造成原因:
* 应用程序试图分配一个超过堆大小的数组

解决方案:
* 使用 -Xmx增加堆大小
* 修复应用程序中分配巨大数组的bug

4.Perm gen 空间

造成原因:
* Perm gen空间包含:类的名字、字段、方法;与类相关的对象数组和类型数组;JIT编译器优化

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

5.Metaspace

造成原因:
* 从Java8开始Perm gen改成了Metaspace,在本机内存中分配class元数据(称为metaspace)。如果metaspace耗尽,则抛出异常

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

6.无法新建本机线程

造成原因:
* 内存不足,无法创建新线程。由于线程在本机内存中创建,报告这个错误表明本机内存空间不足

解决方案:
* 为机器分配更多的内存
* 减少Java堆空间
* 修复应用程序中的线程泄漏
* 增加操作系统级别的限制:ulimit -a;用户进程数增大(-u)1800
* 使用 -Xss减小线程堆栈大小

7.杀死进程或子进程

造成原因:
* 内核任务:内存不足结束器,在可用内存极地的情况下会杀死进程

解决方案:
* 将进程迁移到不同的机器上
* 给机器增加更多内存
* 与其他OOM错误不同,这是由操作系统而非JVM触发的。

8.发生stack_trace_with_native_method

造成原因:
* 本机方法(native method)分配失败
* 打印的堆栈跟踪信息,最顶层的帧是本机方法

解决方案:
* 使用操作系统本地工具进行诊断

发表回复

您的电子邮箱地址不会被公开。

20 − 16 =