OOM三大场景和解决方案

目录

首先,说说什么是OOM?

Java OOM的三大核心场景

场景一、堆内存OOM

类型一:在线OOM分析,这个属于轻量级的分析:

类型二:离线OOM分析,这个属于轻量级的分析:

场景二:元空间(MetaSpace) OOM

什么是元空间(MetaSpace)

元空间(Metaspace) OOM现象

元空间(Metaspace) OOM 原因

如何定位和解决

元空间(Metaspace) OOM 解决办法:

场景三:堆外内存 OOM

堆外内存 OOM 现象

堆外内存 OOM 原因

堆外内存解决OOM对策


首先,说说什么是OOM?

OOM 全称 “Out Of Memory”,表示内存耗尽。

官方说明:Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector.

当 JVM 因为没有足够的内存来为对象分配空间,并且垃圾回收器也已经没有空间可供回收时,就会抛出这个错误。(注:非exception,已经严重到不足以被应用处理)。

为什么会出现 OOM,一般由这些问题引起

  1. 分配过少:JVM 初始化内存小,业务使用了大量内存;或者不同 JVM 区域分配内存不合理

  2. 内存泄漏:某一个对象被频繁申请,不用了之后却没有被释放,发生内存泄漏,导致内存耗尽

内存泄漏:申请使用完的内存没有释放,导致虚拟机不能再次使用该内存,此时这段内存就泄露了。因为申请者不用了,而又不能被虚拟机分配给别人用

内存溢出:申请的内存超出了 JVM 能提供的内存大小,此时称之为溢出

内存泄漏持续存在,最后一定会溢出,两者是因果关系

Java OOM的三大核心场景

图片

场景一、堆内存OOM

OOM的场景和解决方案

图片

分析方法通常有两种:

  • 类型一:在线分析,这个属于轻量级的分析:

  • 类型二:离线分析,这个属于重量级的分析:

类型一:在线OOM分析,这个属于轻量级的分析:

在线OOM分析,包括两种方法:

在线分析方法一:使用 jmap 分析TOP N对象

jmap(Java Memory Map)是jdk自带的java内存映像工具,使用jmap能够系统运行时的内存信息,同时能够将内存dump下来,分析内存泄露的问题。

  • 第一步:jmap 查看进程中占用资源最大的前N个对象,

  • 第二步:知道哪个对象消耗内存了,再去定位代码就不难了。然后 导出 快照文件 jmap -dump:live,format=b,file=文件路径/文件名 pid

这里我们使用它 -dump 选项,将内存信息dump到服务器某个地方,然后传到本地使用内存分析工具MAT进行内存分析。

jmap -dump:live,format=b,file=文件路径/文件名 pidlive:就是只dump 活着的对象 format=b 使用二进制 file= 快照文件保存路径

在线分析方法二:使用 Arthas 在线分析OOM

使用 Arthas 火焰图,分析TOP N对象 和调用堆栈

请参见视频, 和尼恩的《Arthas 学习圣经 v2》 最新版本

类型二:离线OOM分析,这个属于轻量级的分析:

第一步:使用Java内存快照工具:jmap 生成堆转储快照(一般称为headdump或dump文件)。

或者从服务器copy OOM自动dump出来的dump文件。

下面来一份JDK8的JVM参数默认配置

-Xms2g -Xmx2g (按不同容器,4G及以下建议为50%,6G以上,建议设置为70%)
-XX:MetaspaceSize=128m
-XX:MaxMetaspaceSize=512m
-Xss256k
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:AutoBoxCacheMax=20000
-XX:+HeapDumpOnOutOfMemoryError (当JVM发生OOM时,自动生成DUMP文件)
-XX:HeapDumpPath=/usr/local/logs/gc/
-XX:ErrorFile=/usr/local/logs/gc/hs_err_%p.log (当JVM发生崩溃时,自动生成错误日志)
-XX:+PrintGCApplicationStoppedTime
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-Xloggc:/usr/local/heap-dump/
  • -XX:+HeapDumpOnOutOfMemoryError

    从字面就可以很容易的理解,在发生OutOfMemoryError异常时,进行堆的Dump,这样就可以获取异常时的内存快照了。

  • -XX:HeapDumpPath=/usr/local/heap-dump/

这个也很好理解,就是配置HeapDump的路径,

方便我们管理,这里我们配置为/usr/local/heap-dump/,当然你也可以根据自己的需要,定义为其他的目录。

JVM相关的启动参数 给出一些实战经验,让工作中更加从容:

  1. 调优参数务必加上-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=,发生OOM让JVM自动dump出内存,方便后续分析问题解决问题

  2. 堆内存不要设置的特别大,因为你设置的特别大,发生OOM时生成的dump文件就特别大,不好分析。建议不超过8G。

  3. 想主动dump出JVM内存,有挺多方式,但不管哪种方式,主动dump内存会引发STW,请线上压力最小的时间段操作。

    即通过arthas提供的命令heapdump主动dump出JVM的内存,这个操作会引发FGC,背后是STW,操作时请选择好时机,不然老板可能提刀来见。

第2步:导入到jvisualvm进行分析

场景二:元空间(MetaSpace) OOM

什么是元空间(MetaSpace)

JDK8 HotSpot JVM 将移除永久区,使用本地内存来存储类元数据信息并称之为:元空间(Metaspace);这与Oracle JRockit 和IBM JVM’s很相似,如下图所示

图片

这意味着不会再有java.lang.OutOfMemoryError: PermGen 问题,也不再需要你进行调优及监控内存空间的使用……

但请等等,这么说还为时过早。

在默认情况下,这些改变是透明的,接下来我们的展示将使你知道仍然要关注类元数据内存的占用。

请一定要牢记,元空间在直接内存,但是没有  消除类和类加载器导致的内存泄漏

由于永久代PermGen 空间被移除。所以,JVM 8的参数:PermSize 和 MaxPermSize 会被忽略并给出警告(如果在启用时设置了这两个参数)。

元空间是方法区在HotSpot JVM 中的实现,方法区主要用于存储类的信息、常量池、方法数据、方法代码等。方法区逻辑上属于堆的一部分,但是为了与堆进行区分,通常又叫“非堆”。

元空间的本质和永久代类似,都是对JVM规范中方法区的实现。

不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。理论上取决于32位/64位系统可虚拟的内存大小,可见也不是无限制的,需要配置参数。

元空间(Metaspace) 垃圾回收,会对僵死的类及类加载器的垃圾回收会进行回收,元空间(Metaspace) 垃圾回收的时机是,在元数据使用达到“MaxMetaspaceSize”参数的设定值时进行。

元空间(Metaspace) 容量

默认情况下,类元数据只受可用的本地内存限制(容量取决于是32位或是64位操作系统的可用虚拟内存大小)。

一般情况下避免 MetaSpace 耗尽内存,都会设置一个 MaxMetaSpaceSize参数,MaxMetaspaceSize用于限制本地内存分配给类元数据的大小。如果没有指定这个参数,元空间会在运行时根据需要动态调整。

动态的调整会造成元空间数据的复制和GC的消耗,为了避免弹性伸缩带来的额外 GC 消耗,我们会将-XX:MetaSpaceSize和-XX:MaxMetaSpaceSize两个值设置为固定的,但是这样也会导致在空间不够的时候无法扩容,然后频繁地触发 GC,最终 OOM。

在运行过程中,如果实际大小小于这个值,JVM 就会通过 -XX:MinMetaspaceFreeRatio 和 -XX:MaxMetaspaceFreeRatio 两个参数动态控制整个 MetaSpace 的大小。监控和调整元空间对于减小垃圾回收频率和减少延时是很有必要的。

持续的元空间垃圾回收说明,可能存在类、类加载器导致的内存泄漏或是大小设置不合适。

元空间(Metaspace) OOM现象

JVM 在启动后或者某个时间点开始,MetaSpace 的已使用大小在持续增长,同时每次 GC 也无法释放,调大 MetaSpace 空间也无法彻底解决

元空间(Metaspace) OOM 原因

核心原因:生成大量动态类

比如spring的BeanUtils的拷贝对象,json的序列化大量使用反射,

而反射在大量使用时,因为使用了缓存的原因,导致ClassLoader和它引用的Class等对象不能被回收,

反射(包括上面提到的spring的BeanUtils的拷贝对象,json的序列化),而反射在大量使用时,因为使用了缓存的原因,导致ClassLoader和它引用的Class等对象不能被回收,

如何定位和解决

分析dump文件,一般会在日志中发现了“Metaspace OOM”的提示

元空间(Metaspace) OOM 解决办法:

  • 减少代码中,使用反射的情况,或者对反射进行优化。

  • 测试出服务实例的能力上限,进行服务的过载保护比如(限流等),防止突发流量将服务

场景三:堆外内存 OOM

堆外内存 OOM 现象

  • 现象1:Java 进程的 RES 甚至超过了 -Xmx 的大小

  • 现象2:Java 进程假死

Java 进程的 RES 甚至超过了 -Xmx 的大小 怎么看呢?通过 top 命令发现 Java 进程的 RES 甚至超过了** -Xmx 的大小。出现这些现象时,基本可以确定是出现了堆外内存泄漏。

使用top命令查看内存和cpu占用高的java进程,使用下面的命令:

top -c -p $(pgrep -d',' -f java)

图片

top命令查看进程信息, 主要的字段含义如下:

  • PID:进程的标识符。

  • USER:运行进程的用户名。

  • PR(优先级):进程的优先级。

  • NI(Nice值):进程的优先级调整值。

  • VIRT(虚拟内存):进程使用的虚拟内存大小。

  • RES(常驻内存):进程实际使用的物理内存大小。

  • SHR(共享内存):进程共享的内存大小。

  • %CPU:进程占用 CPU 的使用率。

  • %MEM:进程占用内存的使用率。

  • TIME+:进程的累计 CPU 时间。

top命令的res表示实际占用的内存,RES(Resident Set Size)是用来表示进程占用的物理内存的指标之一,它的单位是KB(千字节)。

具体地说,RES是指当前进程正在使用的物理内存大小,它包括了进程自身和它所拥有的子进程使用的内存,但不包括被共享的内存和被交换到磁盘上的内存。

res可能比xmx设置的要大, 因为统计内容不同

  • xmx只是堆内存(包括新生代(eden,from,to),老年代),

  • res范围更广,还包括metaDate,堆外内存等,

堆外内存 OOM 原因

JVM 的堆外内存泄漏,主要有两种的原因:

  • 通过 UnSafe#allocateMemory,ByteBuffer#allocateDirect 主动申请了堆外内存而没有释放,常见于 NIO、Netty 等相关组件。

  • 代码中有通过 JNI 调用 Native Code 申请的内存没有释放。

堆外内存解决OOM对策

  • 进行线上指标监控

    通过反射获取堆外内存的指标,并且通过在线Prometheus+grafana进行采集和 监控,如果堆外内存一直增长,就大概率泄漏

  • 内存泄漏检测进行检测,然后根据找到泄漏的内存,进行Netty引用计数的清零

    一般泄漏都发生在最后一次使用后忘记调用释放方法造成

    通过Netty自带内存泄漏检测工具,配合压力测试,进行内存泄露检测, 解决OOM之后再上线。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/805596.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ant Design Vue

Ant Design Vue是一个由阿里巴巴团队打造的Vue组件库,它以其优雅的设计和丰富的功能集成而被广泛使用。以下是对Ant Design Vue的简单介绍: 首先,Ant Design Vue采用了精良的设计风格,为用户提供了简约、美观的界面,符…

类和对象—初阶

目录 1.面向过程和面向对象初步认识 2.类的引入 3.类的定义 4.类的访问限定符及封装 4.1 访问限定符 【面试题】 4.2 封装 【面试题】 5.类的作用域 6.类的实例化 7.类对象模型 7.1 如何计算类对象的大小 7.2 类对象的存储方式 7.3 结构体内存对齐规则 【面试题】…

LMDoply部署实战

使用LMDeoply部署各类开源大模型,进行推理实践。 一. 环境准备 1. 创建Conda环境 studio-conda -t lmdeploy -o pytorch-2.1.2 2. 安装LMDeploy 激活刚刚创建的虚拟环境。 conda activate lmdeploy 安装0.3.0版本的lmdeploy。 pip install lmdeploy[all]0.3.…

Chrome谷歌下载入口

​hello,我是小索奇 发现好多人说谷歌浏览器在哪里下载呀,哪里可以找到? 你可能会心想,一个浏览器你还不会下载啊? 还真是,有很多伙伴找不到下载入口,为什么呢? Bing进行搜索&am…

4.进程相关 2

8.内存映射 8.1 内存映射相关定义 创建一个文件,将保存在磁盘中的文件映射到内存中,后期两个进程之间对内存中的数据进行操作,大大减少了访问磁盘的时间,也是一种最快的 IPC ,因为进程之间可以直接对内存进行存取 8.…

面试经典算法系列之双指针1 -- 合并两个有序数组

面试经典算法题1 – 合并两个有序数组 LeetCode.88 公众号:阿Q技术站 问题描述 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中&#…

【讲解下Fiddler的安装和使用】

🎥博主:程序员不想YY啊 💫CSDN优质创作者,CSDN实力新星,CSDN博客专家 🤗点赞🎈收藏⭐再看💫养成习惯 ✨希望本文对您有所裨益,如有不足之处,欢迎在评论区提出…

宠物救助系统|基于Springboot和vue的流浪猫狗救助救援系统设计与实现(源码+数据库+文档)

宠物救助目录 基于Springboot和vue的流浪猫狗救助救援系统设计与实现 一、前言 二、系统设计 三、系统功能设计 1、前台: 2、后台 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取: 博主介绍:✌…

面试经典算法系列之链表2 -- 环形链表

面试经典算法8-环形链表 LeetCode.141 公众号:阿Q技术站 问题描述 给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环&am…

【C++成长记】C++入门 |函数重载、引用、内联函数

🐌博主主页:🐌​倔强的大蜗牛🐌​ 📚专栏分类:C❤️感谢大家点赞👍收藏⭐评论✍️ 目录 一、函数重载 1、函数重载概念 二、引用 1、引用概念 2、引用特性 3、常引用 4、使用场景 5、…

数据库之DCL操作(用户、访问权限。)

DCL英文全称是Data control language(数据控制语言),用来管理数据库用户、控制数据库的访问权限。 1.管理用户 1.1查询用户 select * from mysql.user; 其中 Host代表当前用户访问的主机,如果为localhost,仅代表只能够在当前本机访问&…

深入浅出 -- 系统架构之微服务中OpenFeign最佳实践

前面我们讲了一下 Ribbon 和 RestTemplate 实现服务端通信的方法,Ribbon 提供了客户端负载均衡,而 RestTemplate 则对 http 进行封装,简化了发送请求的流程,两者互相配合,构建了服务间的高可用通信。 但在使用后也会发…

谁在投资“元素周期表”? 顶级芯片制造商“军备竞赛”

有色和商品基金的大买家何在 投资A股,有时候投资的也是一种“玄妙”的境界。 你需要复习金融知识、复习经济知识,复习科技知识,学习财政学、学习人口学、学习传染病学。 但这些可能还不够。 你能想象么有朝一日,你会回头复习中…

Flask项目如何在测试环境和生产环境部署上线

前言 最近在使用Flask框架,写一个小项目,在项目部署启动后,出现了以下这段提示,这段提示的意思是,该启动方式适用于开发环境中,生产环境要使用WSGI服务器。 WARNING: This is a development server. Do no…

OSCP靶场--Zino

OSCP靶场–Zino 考点(CVE-2019-9581 RCE 定时任务脚本可写提权) 1.nmap扫描 ##┌──(root㉿kali)-[~/Desktop] └─# nmap 192.168.173.64 -sV -sC -Pn --min-rate 2500 -p- Starting Nmap 7.92 ( https://nmap.org ) at 2024-04-10 04:18 EDT Nmap scan report for 192.…

自定义注解进行数据转换

前言: Java注解是一种元数据机制,可用于方法,字段,类等程序上以提供关于这些元素的额外信息。 以下内容是我自己写的一个小测试的demo,参考该文章进行编写:https://blog.csdn.net/m0_71621983/article/details/1318164…

【linux】基础IO(四)

在上一篇基础IO中我们主要讲述了文件再磁盘中的存储,当然我们说的也都只是预备知识,为这一篇的文件系统进行铺垫。 目录 搭文件系统的架子:填补细节:inode:datablock[]: 更上层的理解: 搭文件系统的架子&a…

uniapp 2.0可视化工具:创建与管理Vue文件的实践之旅

引言 在前端开发领域中,Vue以其简洁、易上手的特点,受到了广大开发者的青睐。随着uniapp的不断发展,越来越多的开发者开始利用uniapp的可视化工具来创建和管理Vue文件,以提高开发效率。本文将详细介绍如何使用uniapp 2.0可视化工…

bytetrack复现

一,环境安装 创建虚拟环境 conda create -n bytetrack python=3.8 安装requirements pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple 可能报错,解决办法,安装numpy 安装 pytorch pip install torch==1.12.0+cu113 torchvision==0.13.0+cu1…

H5动效开发之CSS3动画

动画效果是情感设计的重要手段,在H5开发中,实现动效需要综合利用 JavaScript、CSS(3)、SVG、Canvas 等多种 Web 技术手段才能开发出动人的网页动态效果。 接下来,我们把重心放在 CSS3 动画上面,因为 CSS3 在现如今的网页动效开发中占据着最为重要的一席,作为老大哥 CSS 的…