当前位置:网站首页>发生OOM了,你知道是什么原因吗,又该怎么解决呢?
发生OOM了,你知道是什么原因吗,又该怎么解决呢?
2022-07-06 09:01:00 【笑看风云路】
目录
前言
撸java代码的同学,多多少少都会碰到内存溢出(OOM)的场景,但是造成OOM原因却不止一个。今天就来总结一下常见的OOM的原因以及解决方案。
1、堆内存不足(Java heap space)
原因:
- 代码中可能存在大对象分配,通常是一个大树组。
- 可能存在内存泄露,导致多次GC之后,还是无法找到一块足够大的内存容纳当前对象,常见于使用了File等资源没有回收。
- 超出预期的访问量、数据量,通常是上游系统请求流量飙升,常见于各类促销、秒杀活动,可以结合业务流量指标排查是否有尖状峰值。
解决方案:
- 针对大部分的情况,通常只需要通过-Xmx参数调高JVM堆内存即可。如果仍然没有解决,可以参考下面几种情况进行处理。
- 如果是超大对象,检查其合理性,比如是否一次查询了数据库全部结果,而没有做结果数限制。
- 如果是业务峰值压力,可以考虑添加机器资源,或者做限流降级操作。
- 如果是内存泄露,需要找到持有对象,修改代码设计,比如关闭没有释放的连接。
2、永久代空间/元空间(Permgen space/ metaspace)
原因:
- 永久代是HotSot虚拟机对方法区的具体实现,存放被虚拟机加载的类信息、常量池、静态变量,JIT编译后的代码等
- Perngen的使用量和加载到内存的class的数量/大小正相关
解决方案:
- 检查是否永久代空间(启动参数:-XX:MaxPermSize)或者元空间(启动参数:-XX:MaxMetaspaceSize)设置的过小。
- 检查代码中是否存在大量反射操作
- dump之后通过mat检查是否存在大量由于反射生成的代理类
- 应用部署时报错,很可能没有重启应用,导致加载了多份class信息,重启JVM即可解决
3、GC overhead limit exceeded
原因:
- 当java进程花费98%以上时间来做GC并且回收了不到2%的堆内存时会抛出此异常。
- 堆内存太小
解决方案:
- 检查项目中是否有大量的死循环或者使用大内存的代码,优化代码
- dump内存,检查是否存在内存泄露,如果没有,加大内存。
4、方法栈溢出(Unable to create new native thread)
原因:
- 线程数超过操作系统最大线程数ulimit限制
- 线程数超过kernal.pid_max
- native 内存不足
解决方案:
- 升级配置,为机器提供更多内存
- 降低Java heap space大小
- 修复应用程序的线程泄露问题
- 限制线程池大小
- 使用-Xss参数减少线程栈大小
- 调高OS层面的线程最大数:执行ulimit -a 查看最大线程数限制,使用ulimit -u xx 调整最大线程数限制
5、swap区溢出(Out of swap space)
该错误表示所有可用的虚拟内存已被耗尽。虚拟内存(Virtual Memory)由物理内存(Physical)和交换空间(Swap Space)两部分组成。当运行时程序请求的虚拟内存溢出时就会报 Out of swap space错误。
原因:
- 地址空间不足
- 物理内存已耗光
- 应用程序的本地内存泄露,例如不断申请本地内存,却不释放
- 执行jmap -histo:live 命令,强制执行Full GC;如果执行几次后内存明显下降,则基本确认为Direct ByteBuffer问题
解决方案:
- 升级地址空间为64bit
- 使用Arthas检查是否为Inflater/Deflater 解压问题,如果是,则显示调用end方法
- Direct ByteBuffer问题可以通过启动参数–XX:MaxDirectMemorySize降低阈值
- 加大swap分区大小或者加大机器内存大小
- 隔离部署,避免争抢
6、分配超大数组(Requested array size exceeds VM limit)
原因:
这种情况一般是由于不合理数组分配请求导致的,在为数组分配内存之前,JVM会执行一项检查。要分配的数组在该平台是否可以寻址,如果不能寻址就会抛出这个错误。
解决方案:
检查代码中是否有创建超大数组的地方
7、Direct buffer memory
Java允许应用程序通过Direct ByteBuffer直接访问堆外内存,许多高性能程序通过Direct ByteBuffer结合内存映射文件(Memory MappedFile)实现高速IO
原因:
Direct ByteBuffer的默认大小为64MB,一旦使用超出限制,就会抛出Direct buffer memory错误。
解决方案:
Java只能通过ByteBuffer.allocateDirect方法使用DirectByteBuffer,因此,可以通过Arthas等在线诊断工具拦截该方法进行排查。
- 检查是否直接或间接使用了NIO,如netty,jetty等
- 通过启动参数-XX:MaxDirectMemorySize调整Direct ByteBuffer上限值
- 检查JVM参数是否有-XX:+DisableExplicitGC选项,如果有去掉,因为该参数会使System.gc()失效
- 检查堆外内存的代码,确认是否存在内存泄露;或者通过反射调用sun.misc.Cleaner的clean() 方法来主动释放Direct ByteBuffer持有的内存空间。
- 内存容量确实不够的,升级配置
8、Kill process or sacrifice child
有一种内核作业(Kernel Job)名为 Out of Memory Killer,它会在可用内存极低的情况下“杀死”(kill)某些进程。OOM Killer 会对所有进程进行打分,然后将评分较低的进程“杀死”,具体的评分规则可以参考 Surviving the Linux OOM Killer。
不同于其他的 OOM 错误,Kill processorsacrifice child错误不是由 JVM 层面触发的,而是由操作系统层面触发的。
原因:
默认情况下,Linux 内核允许进程申请的内存总量大于系统可用内存,通过这种“错峰复用”的方式可以更有效的利用系统资源。
然而,这种方式也会无可避免地带来一定的“超卖”风险。例如某些进程持续占用系统内存,然后导致其他进程没有可用内存。此时,系统将自动激活 OOM Killer,寻找评分低的进程,并将其“杀死”,释放内存资源。
解决方案:
- 升级服务器配置/隔离部署,避免争用。
- OOM Killer 调优。
结语
好了,今天就为大家分享到这里了。如果本文对你有帮助的话,欢迎点赞&收藏&分享,这对我继续分享&创作优质文章非常重要。感谢
-------------- end ----------------
微信公众号:扫描下方二维码
或 搜索 笑看风云路
关注,获取更多大数据干货!
边栏推荐
- Le modèle sentinelle de redis
- 【shell脚本】使用菜单命令构建在集群内创建文件夹的脚本
- QML control type: menu
- 运维,放过监控-也放过自己吧
- Mapreduce实例(八):Map端join
- Meituan Er Mian: why does redis have sentinels?
- Design and implementation of online shopping system based on Web (attached: source code paper SQL file)
- Global and Chinese markets of SERS substrates 2022-2028: Research Report on technology, participants, trends, market size and share
- Activiti7工作流的使用
- 一篇文章带你了解-selenium工作原理详解
猜你喜欢
Selenium+pytest automated test framework practice
Redis之连接redis服务命令
requests的深入刨析及封装调用
基于B/S的网上零食销售系统的设计与实现(附:源码 论文 Sql文件)
为拿 Offer,“闭关修炼,相信努力必成大器
Intel distiller Toolkit - Quantitative implementation 2
The five basic data structures of redis are in-depth and application scenarios
[shell script] - archive file script
工作流—activiti7环境搭建
[OC foundation framework] - [set array]
随机推荐
Advanced Computer Network Review(4)——Congestion Control of MPTCP
MySQL数据库优化的几种方式(笔面试必问)
[OC foundation framework] - [set array]
Leetcode problem solving 2.1.1
Global and Chinese market of AVR series microcontrollers 2022-2028: Research Report on technology, participants, trends, market size and share
Selenium+pytest automated test framework practice
Design and implementation of online shopping system based on Web (attached: source code paper SQL file)
IDS cache preheating, avalanche, penetration
Chapter 1 :Application of Artificial intelligence in Drug Design:Opportunity and Challenges
美团二面:为什么 Redis 会有哨兵?
有软件负载均衡,也有硬件负载均衡,选择哪个?
Different data-driven code executes the same test scenario
Redis之Geospatial
Design and implementation of online snack sales system based on b/s (attached: source code paper SQL file)
【shell脚本】——归档文件脚本
Five layer network architecture
Redis分布式锁实现Redisson 15问
一文读懂,DDD落地数据库设计实战
Connexion d'initialisation pour go redis
Selenium+Pytest自动化测试框架实战