1篇文章搞清楚8种JVM内存溢出(OOM)的原因和解决方法

Java多线程如何引发OOM—多线程开发知识点 Java —ThreadLocal 如何引发 OOMJava 内存泄漏ThreadLocal_OOM回顾ThreadLocal强引用软引用弱引用虚引用 Java 内存泄漏 内存溢出(Out Of Memory):是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于能提供的最大内存。此时程序就运行不了,系统会提示内存溢出,有时候会自动关闭软件,重启电脑或者软件后释放掉一部分内存又可以正常运行该软件,而由系统配置、数据流、用户代码等原因而导致的内存溢出错误,即使用户重新执行任务依然 阅读详情

前言

撸Java的同学,多多少少会碰到内存溢出(OOM)的场景,但造成OOM的原因却是多种多样。

 

堆溢出

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

java.lang.OutOfMemoryError: Java heap space

原因

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

解决方法

1、检查是否存在大对象的分配,最有可能的是大数组分配
2、通过jmap命令,把堆内存dump下来,使用mat工具分析一下,检查是否存在内存泄露的问题
3、如果没有找到明显的内存泄露,使用 -Xmx 加大堆内存
4、还有一点容易被忽略,检查是否有大量的自定义的 Finalizable 对象,也有可能是框架内部提供的,考虑其存在的必要性

欢迎大家关注我的公种浩【程序员追风】,文章都会在里面更新,整理的资料也会放在里面。

 

永久代/元空间溢出

报错信息:

java.lang.OutOfMemoryError: PermGen spacejava.lang.OutOfMemoryError: Metaspace

原因

永久代是 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.

解决方法

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

1、检查是否永久代空间或者元空间设置的过小
2、检查代码中是否存在大量的反射操作
3、dump之后通过mat检查是否存在大量由于反射生成的代理类
4、放大招,重启JVM

 

GC overhead limit exceeded

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

java.lang.OutOfMemoryError:GC overhead limit exceeded

原因

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

解决方法

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

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

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

 

方法栈溢出

报错信息:

java.lang.OutOfMemoryError : unable to create new native Thread

原因

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

解决方法

1、通过 -Xss 降低的每个线程栈大小的容量 2、线程总数也受到系统空闲内存和操作系统的限制,检查是否该系统下有此限制:

  • /proc/sys/kernel/pid_max

  • /proc/sys/kernel/thread-max

  • maxuserprocess(ulimit -u)

  • /proc/sys/vm/maxmapcount

 

非常规溢出

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

分配超大数组

报错信息 :

java.lang.OutOfMemoryError: Requested array size exceeds VM limit

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

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

 

swap溢出

报错信息 :

java.lang.OutOfMemoryError: Out of swap space
这种情况一般是操作系统导致的,可能的原因有:

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

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

解决方案:

1、其它服务进程可以选择性的拆分出去
2、加大swap分区大小,或者加大机器内存大小

 

本地方法溢出

报错信息 :

java.lang.OutOfMemoryError: stack_trace_with_native_method

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

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

 

最后

欢迎大家关注我的公种浩【程序员追风】,文章都会在里面更新,整理的资料也会放在里面。

Java 中各种内存溢出的问题剖析 Java开发领域,内存溢出(OutOfMemory,简称OOM)犹如一颗隐藏的“定时炸弹”,随时可能让程序崩溃,给用户带来糟糕的体验。今天,就让我们深入探究Java中各类内存溢出问题,了解其根源、排查方法以及有效的修改策略。 阅读详情

相关推荐

如果在线上遇到了OOM,该如何解决

线上如遇到 JVM 内存溢出,可以分以下几步排查jmap -heap 查看是否内存分配过小jmap -histo 查看是否有明显的对象分配过多且没有释放情况jmap -dump 导出 JVM 当前内存快照,使用 JDK 自带或 MAT 等工具分析快照如果上面还不能定位问题,那么需要排查应用是否在不断创建资源,比如网络连接或者线程,都可能会导致系统资源耗尽。...

Park33的博客 935

内存溢出原因解决办法

🏆今日学习目标:🍀内存溢出原因解决办法✅创作者:林在闪闪发光⏰预计时间:30分钟。

林在闪闪发光的博客 4387

什么是内存溢出(Out Of Memory---OOM内存泄露 (Memory Leak)

1内存溢出:(Out Of Memory---OOM) 系统已经不能再分配出你所需要的空间,比如系统现在只有1G的空间,但是你偏偏要2个G空间,这就叫内存溢出 例子:一个盘子用尽各种方法只能装4个果子,你装了5个,结果掉倒地上不能吃了。这就是溢出。 比方说栈,栈满时再做进栈必定产生空间溢出,叫上溢,栈空时再做退栈也产生空间溢出,称为下溢。就是分配的内存不足以放下数据项序列,称为内存溢出。说白了就是我承受不了那么多,那就报错。 2、内存泄漏: (Memory Leak) 强引用所指向的对...

小小鱼儿小小林的博客 1万+

导致溢出_1篇文章搞清楚8JVM内存溢出OOM)的原因解决方法

前言撸Java的同学,多多少少会碰到内存溢出(OOM)的场景,但造成OOM原因却是多种多样。堆溢出这种场景最为常见,报错信息:原因1、代码中可能存在大对象分配 2、可能存在内存泄露,导致在多次GC之后,还是无法找到一块足够大的内存容纳当前对象。解决方法1、检查是否存在大对象的分配,最有可能的是大数组分配 2、通过jmap命令,把堆内存dump下来,使用mat工具分析一下,检查是否存在内存泄露的问...

weixin_42100032的博客 884

tomcat 内存溢出_1篇文章搞清楚8JVM内存溢出OOM)的原因解决方法

前言撸Java的同学,多多少少会碰到内存溢出(OOM)的场景,但造成OOM原因却是多种多样。堆溢出这种场景最为常见,报错信息:原因1、代码中可能存在大对象分配 2、可能存在内存泄露,导致在多次GC之后,还是无法找到一块足够大的内存容纳当前对象。解决方法1、检查是否存在大对象的分配,最有可能的是大数组分配 2、通过jmap命令,把堆内存dump下来,使用mat工具分析一下,检查是否存在内存泄露的问...

weixin_39534780的博客 545

oom 如何避免 高并发_1篇文章搞清楚8JVM内存溢出OOM)的原因解决方法

前言撸Java的同学,多多少少会碰到内存溢出(OOM)的场景,但造成OOM原因却是多种多样。堆溢出这种场景最为常见,报错信息:java.lang.OutOfMemoryError:Javaheapspace原因1、代码中可能存在大对象分配2、可能存在内存泄露,导致在多次GC之后,还是无法找到一块足够大的内存容纳当前对象。解决方法1、检查是否存在大对象的分配,最有可能的是大数组分配2、通过j...

weixin_32667439的博客 562

1篇文章搞清楚8JVM内存溢出OOM)的原因解决方法(恭喜fpx)

【北京】 IT技术人员面对面试、跳槽、升职等问题,如何快速成长,获得大厂入门资格升职加薪的筹码?与大厂技术大牛面对面交流,解答你的疑惑。《从职场小白到技术总监成长之路:我的职场焦虑与救赎》活动链接:码客 恭喜fpx,新王登基,lpl*b 我们是冠军 前言 撸Java的同学,多多少少会碰到内存溢出OOM)的场景,但造成OOM原因却是多种多样。 堆溢出 这种场景最为常见,报错信息:...

wanghao112956的博客 346

JVM遇到OOM如何排错,如何使用工具分析问题所在,这篇文章告诉你!

篇文章只讲述在遇到 OOM (java.lang.OutOfMemoryError:Java heap space) 这种情况如何利用工具分析问题,找到问题所在,关于JVM原理这方面的不过多深究。大家有兴趣的可以自行百度 本篇参考:狂神说 Java https://www.bilibili.com/video/BV1iJ411d7jS?p=9 文章目录步骤一:准备一个简单的案例步骤二:下载 jprofiler 分析工具第三步:IDEA 插件安装第四步:运行代码(设置 JVM 运行参数)步骤五:JPro.

永远年轻 1870

超快速定位OOM内存溢出问题)

看完这篇文章,大家能获得的知识: 1、什么是OOM 2、为什么会发生OOM 3、哪些区域会发生OOM 4、JVM进程挂了,会有哪些可能性 5、生产环境的JVM无响应了,如何快速定位问题 6、子牙老师给你的一些成熟的调优建议 1. 什么是OOM OOM是Out Of Memory的缩写。即内存溢出。 2. 为什么会发生OOM 如果面试官问这个问题,我知道每个人都能说一大堆,但是我希望大家就回答下面三句话,言简意赅: 业务正常运行起来就需要比较多的内存,而给JVM设置的内存过小。具体表

Java搜索工程技术栈 6333

java oom产生原因_JVM发生OOM原因JVM内存溢出原因,及解决办法

篇文章主要是对java程序运行在JVM上可能产生内存溢出(OOM)的情况进行整理…1. Java 堆空间发生频率:5颗星造成原因1、无法在 Java 堆中分配对象2、吞吐量增加3、应用程序无意中保存了对象引用,对象无法被 GC 回收4、应用程序过度使用 finalizer。finalizer 对象不能被 GC 立刻回收。finalizer 由结束队列服务的守护线程调用,有时 finalizer ...

weixin_42361666的博客 603

JVMOOM类型及解决方案

jmap -heap查看是否内存分配过小;查看是否有明显的对象分配过多且没有释放情况;jmap -dump导出 JVM 当前内存快照,使用 JDK 自带或 MAT 等工具分析快照。如果上面还不能定位问题,那么需要排查应用是否在不断创建资源,比如网络连接或者线程,都可能会导致系统资源耗尽。

weixin_46956020的博客 850

JVM 内存结构基于JDK1.8JVM篇三】

在我的上一篇文章别翻了,这篇文章绝对让你深刻理解java类的加载以及ClassLoader源码分析【JVM篇二】中,相信大家已经对java类加载机制有一个比较全面的理解了,那么类加载之后,字节码数据在 Java 虚拟机内存中是如何存放的 ?Java 虚拟机在为类实例或成员变量分配内存是如何分配的 ?是的,这两个问题就涉及到了JVM 内存结构的知识了,那么这篇文章将进行解答。 文章目录1、内存结构还...

宜春 4362

JVM调优实战之OOM

OOMJVM调优相关的问题一直是难点,只能感叹,大家都太不容易了。明明只是小白、明明只想找份工作、明明没有机会接触到OOM与调优……却被现实逼着要去搞懂JVMOOM、调优……本篇文章是结合大厂与小厂的同学们问的问题,结合我的工作经历整理总结而来。看懂、理解、背下来,当面试官再问你OOM与调优,一定被你征服。 看完这篇文章,大家能获得的知识: 1、什么是OOM 2、为什么会发生OOM 3、哪些区域会发生OOM 4、JVM进程挂了,会有哪些可能性 5、生产环境的JVM无响应了,如何快速定位问题 什么是OOM

m0_46527847的博客 860

【一看就懂,如何定位解决jvm发生OOM问题】

通过上述步骤,我们可以系统性地排查解决JVM OOM问题。关键在于理解OOM异常的类型、捕获详细的异常信息、分析GC日志堆Dump文件,以及采取相应的解决措施。持续监控预警机制也可以帮助预防OOM问题,确保应用的稳定运行。

qq_33545255的博客 1220

JVM-OOM-不同类型的OOM问题定位

如上图,我们点击【Histogram】柱状图后发现除了char[]String以外有一个ConcurrentHashMap是占内存最大的,这就有点奇怪(其实是因为:ConcurrentHashMap 来缓存从数据库查询得到的数据或其索引导致的),但是这里我在这里并没有定位到具体的代码位置,我们继续通过【Dominator Tree】进一步分析。可能会有朋友说,那不行,我这个Mapper下的sql特别多,我不想一个个看,我就想明确的知道问题出在了哪里我才能去解决。这是内存快照中实际存在的对象实例个数。

yeYingXuan的博客 1251

如果线上遇到了OOM,该如何解决

OOM 意味着程序存在着漏洞,可能是代码或者 JVM 参数配置引起的。这篇文章读者聊聊,Java 进程触发了 OOM 后如何排查常说对生产环境保持敬畏之心,快速解决问题也是一种敬畏的表现。

qq_42600094的博客 2432
上一篇: 1篇文章全面总结2019年Java面试知识,掌握这些你也能进大厂!
下一篇: B树?这篇文章彻底看懂了!
程序员追风
程序员追风 优质创作者: Java技术领域 优质创作者: Java技术领域
博客等级 码龄7年 9635粉丝 237原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值