本文源自转载:JVM出现OOM的八种原因及解决办法

目录

一、堆溢出

1.1 原因

1.2解决方法

二、永久代/元空间溢出

2.1 原因

2.2 解决方法

三、GC overhead limit exceeded

3.1 原因

3.2 解决方法

四、方法栈溢出

4.1 原因

4.2 解决方法

五、非常规溢出

5.1 分配超大数组

5.2 swap溢出

5.3 解决方案

六、本地方法溢出


一、堆溢出

这种场景最为常见,报错信息:

java.lang.OutOfMemoryError: Java heap space复制代码

1.1 原因

1、代码中可能存在大对象分配

2、可能存在内存泄露,导致在多次GC之后,还是无法找到一块足够大的内存容纳当前对象。

1.2解决方法

1、检查是否存在大对象的分配,最有可能的是大数组分配

2、通过jmap命令,把堆内存dump下来,使用mat工具分析一下,检查是否存在内存泄露的问题

3、如果没有找到明显的内存泄露,使用 -Xmx 加大堆内存

4、还有一点容易被忽略,检查是否有大量的自定义的 Finalizable 对象,也有可能是框架内部提供的,考虑其存在的必要性

二、永久代/元空间溢出

报错信息:

java.lang.OutOfMemoryError: PermGen spacejava.lang.OutOfMemoryError: Metaspace复制代码

2.1 原因

永久代是 HotSot 虚拟机对方法区的具体实现,存放了被虚拟机加载的类信息、常量、静态变量、JIT编译后的代码等。

JDK8后,元空间替换了永久代,元空间使用的是本地内存,还有其它细节变化:

  • 字符串常量由永久代转移到堆中
  • 和永久代相关的JVM参数已移除

可能原因有如下几种:

1、在Java7之前,频繁的错误使用String.intern()方法

2、运行期间生成了大量的代理类,导致方法区被撑爆,无法卸载

3、应用长时间运行,没有重启

没有重启 JVM 进程一般发生在调试时,如下面 tomcat 官网的一个 FAQ:

Why does the memory usage increase when I redeploy a web application?

That is because your web application has a memory leak.

A common issue are “PermGen” memory leaks. They happen because the Classloader (and the Class objects it loaded) cannot be recycled unless some requirements are met (). They are stored in the permanent heap generation by the JVM, and when you redeploy a new class loader is created, which loads another copy of all these classes. This can cause OufOfMemoryErrors eventually.

(*) The requirement is that all classes loaded by this classloader should be able to be gc’ed at the same time.

2.2 解决方法

因为该OOM原因比较简单,解决方法有如下几种:

1、检查是否永久代空间或者元空间设置的过小

2、检查代码中是否存在大量的反射操作

3、dump之后通过mat检查是否存在大量由于反射生成的代理类

4、放大招,重启JVM

三、GC overhead limit exceeded

这个异常比较的罕见,报错信息:

java.lang.OutOfMemoryError:GC overhead limit exceeded复制代码

3.1 原因

这个是JDK6新加的错误类型,一般都是堆太小导致的。Sun 官方对此的定义:超过98%的时间用来做GC并且回收了不到2%的堆内存时会抛出此异常

3.2 解决方法

1、检查项目中是否有大量的死循环或有使用大内存的代码,优化代码。

2、添加参数 -XX:-UseGCOverheadLimit 禁用这个检查,其实这个参数解决不了内存问题,只是把错误的信息延后,最终出现 java.lang.OutOfMemoryError: Java heap space。

3、dump内存,检查是否存在内存泄露,如果没有,加大内存。

四、方法栈溢出

报错信息:

java.lang.OutOfMemoryError : unable to create new native Thread复制代码

4.1 原因

出现这种异常,基本上都是创建的了大量的线程导致的,以前碰到过一次,通过jstack出来一共8000多个线程。

4.2 解决方法

1、通过 -Xss 降低的每个线程栈大小的容量

2、线程总数也受到系统空闲内存和操作系统的限制,检查是否该系统下有此限制:

  • /proc/sys/kernel/pid_max
  • /proc/sys/kernel/thread-max
  • maxuserprocess(ulimit -u)
  • /proc/sys/vm/maxmapcount

五、非常规溢出

下面这些OOM异常,可能大部分的同学都没有碰到过,但还是需要了解一下

5.1 分配超大数组

报错信息 :

java.lang.OutOfMemoryError: Requested array size exceeds VM limit复制代码

这种情况一般是由于不合理的数组分配请求导致的,在为数组分配内存之前,JVM 会执行一项检查。要分配的数组在该平台是否可以寻址(addressable),如果不能寻址(addressable)就会抛出这个错误。

解决方法就是检查你的代码中是否有创建超大数组的地方。

5.2 swap溢出

报错信息 :

java.lang.OutOfMemoryError: Out of swap space复制代码

这种情况一般是操作系统导致的,可能的原因有:

1、swap 分区大小分配不足;

2、其他进程消耗了所有的内存。

5.3 解决方案

1、其它服务进程可以选择性的拆分出去

2、加大swap分区大小,或者加大机器内存大小

六、本地方法溢出

报错信息 :

java.lang.OutOfMemoryError: stack_trace_with_native_method复制代码

本地方法在运行时出现了内存分配失败,和之前的方法栈溢出不同,方法栈溢出发生在 JVM 代码层面,而本地方法溢出发生在JNI代码或本地方法处。

这个异常出现的概率极低,只能通过操作系统本地工具进行诊断,难度有点大,还是放弃为妙。

JVM出现OOM的八种原因及解决办法相关推荐

  1. JVM发生OOM的 8 种原因、及解决办法

    转载自  JVM发生OOM的 8 种原因.及解决办法 1.Java 堆空间 发生频率:5颗星 造成原因 无法在 Java 堆中分配对象 吞吐量增加 应用程序无意中保存了对象引用,对象无法被 GC 回收 ...

  2. java 内存 溢出_java内存溢出的几种原因和解决办法是什么?

    java内存溢出的几种原因和解决办法是什么? java内存溢出的几种原因和解决办法是: 第一类内存溢出,也是大家认为最多,第一反应认为是的内存溢出,就是堆栈溢出: 那什么样的情况就是堆栈溢出呢?当你看 ...

  3. linux下hg无法运行_Linux 无法启动常见的几种原因及解决办法

    导致 Linux 无法启动的原因有很多,下面良许小编就将常见的几种原因及解决办法进行详述,希望对大家有所帮助. 文件系统配置不当,如 /etc/inittab文件./etc/fstab 文件等配置错误 ...

  4. 内存溢出的几种原因和解决办法

    对于JVM的内存写过的文章已经有点多了,而且有点烂了,不过说那么多大多数在解决OOM的情况,于此,本文就只阐述这个内容,携带一些分析和理解和部分扩展内容,也就是JVM宕机中的一些问题,OK,下面说下O ...

  5. 导致大量kworker的原因_氨氮超标的几种原因及解决办法

    一.有机物导致的氨氮超标 CN 比小于 3 的高氨氮污水,因脱氮工艺要求 CN 比在 4~6,所以需要投加碳源来提高反硝化的完全性.当时投加的碳源是甲醇,因为某些原因甲醇储罐出口阀门脱落,大量甲醇进入 ...

  6. 关于-/bin/sh:xx(命令) not found 的几种原因和解决办法

    编写背后:昨天移植无线网卡到mini2440基本完成到最后一步:用命令:iwlist scanning  搜索网络时串口终端却出现了 -/bin/sh: iwlist  not  found ,后来请 ...

  7. fiddler抓包——手机添加代理后APP连不上网的常见4种原因及解决办法

    更新 遇到的问题是: Android6.0及以下系统可以抓包,而Android7.0及以上系统不能再抓包. 原因: Android7.0+的版本新增了证书验证,即app内不再像原来一样默认信任用户的证 ...

  8. 内存溢出的几种原因和解决办法是什么?

    内存溢出是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于虚拟机能提供的最大内存. 引起内存溢出的原因有很多种,常见的有以下几种: 内存中加载的数据量过于庞大,如一次从 ...

  9. php100并发cpu告警,多线程并发导致CPU100%的一种原因和解决办法

    在用自定义线程池的时候,遇到cpu100%,经过验证后,发现问题来源于我定义的子线程. 子线程的主要功能是从任务队列(LinkedBlockingQueue)里面持续拿出任务,并且执行. 以下为令CP ...

最新文章

  1. CloudCompare 的简单的使用说明
  2. [Leedcode][JAVA][第25题][K个一组反转链表][链表][递归]
  3. Applied Functional Analysis(Applications to Mathematical Physics ) E.Zeidler
  4. rnn 简要_注重文化的简要招聘指南
  5. scala的数值类型(三)
  6. 问题 G: Search Problem (IV)
  7. idea输出目录详解
  8. C++的Memcpy与Memcpy_s函数解析
  9. 松下伺服电机uvw接线图_伺服电机接线图图解
  10. 关于ArcMap中道路、河道中心线提取过程
  11. 发布轻开平台移动App服务器
  12. Faiss:Facebook 开源的相似性搜索类库
  13. 【Python 日志】
  14. 【CTF WriteUp】2020电信和互联网行业赛个人赛部分Crypto题解
  15. The bean ‘employServiceImpl‘ could not be injected as a ‘com.itcast.reggie.service.impl.EmployServic
  16. Pycharm 让编辑区/代码区背景色为白色或与主题色不同
  17. C语言生成随机数的函数,为什么循环后随机数都一样?
  18. 闲鱼自动刷新最新发布页面源码
  19. 搜狗网盟CTR预估的进化之路
  20. 2018 iOS 面试题大全(补充完整版)

热门文章

  1. 其实,男人也需要被疼爱
  2. Zookeeper在Dubbo中的作用及Zk集群的选举原理
  3. 利用亚马逊AWS搭建个人服务器
  4. 采用超级电容器单独供电的BLDC调速控制系统设计分析与实现
  5. PowerDesigner创建导出模版,并生成数据库文档(word文档)
  6. button鼠标离开样式修改_WPF 的Button怎么控制鼠标滑过和点击的样式
  7. 码出高效:Java开发手册笔记(线程安全)
  8. 高通导航器软件开发包使用指南(13)
  9. MAC添加SSH到GitHub
  10. 使用乾坤微前端nginx和服务器部署