Kill OOM

1、什么是OOM?

OOM是每个程序员早晚都必须面对的问题,通常情况下,Java程序员所说的OOM是JVM OOM,即java.lang.OutOfMemoryError,是指Java程序在运行时申请内存超过JVM可用内存限制,导致JVM无法继续分配内存,从而导致程序无法正常执行,因此对于程序员来说,定位和解决OOM是非常重要的。
OOM对程序的影响是重大的。如果是局部对象过大导致的OOM,相应的线程栈会被销毁,相应的局部对象也会被GC快速回收,JVM可以继续处理其他请求。这说明局部对象过大导致的溢出只会导致当前线程中断,不会影响其他线程。如果是静态对象、共享对象或大量对象发生内存溢出,大量业务对象一直占用主要内存,无法有效回收垃圾,进一步导致频繁Full GC。又因为Full GC占用CPU,导致CPU飙升,业务线程的优先级也会降低,基本上处于静止状态,处理效率非常慢,进而先后引发网关504超时异常、503服务不可用异常。严重情况下,JVM OOM也会引发Linux的OOM killer。这是因为Linux内核有个机制叫OOM killer(Out-Of-Memory killer),该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了防止内存耗尽,Linux内核会把Java程序杀掉。无论哪种影响,都有可能导致数据丢失、用户体验下降、维护成本增加,对应用产生重大不利影响。

2、什么场景下会引发OOM?

OOM对应用影响重大,我们需要了解OOM发生的场景和原因,规避或防止OOM的发生,常见的OOM场景有:
内存泄漏:当应用程序申请内存后,没有及时释放,导致内存持续占用,最终导致内存耗尽,引发OOM;
大量对象的申请:当应用程序申请大量的对象时,会占用大量的内存,如果内存不足,则会引发OOM;
死循环或高并发访问:当应用程序中存在死循环或高并发时,会一直占用CPU和内存,最终导致OOM。
由于场景不同,诱发的OOM种类又有所不同,常见的OOM根据JVM规范大致可划分为堆内存溢出、元空间(永久代)溢出、直接内存溢出、栈内存溢出等。虽然OOM细分种类不同,但是解决每个OOM都需要经历信息收集-分析定位-解决问题的过程。

3、如何快速定位OOM?

OOM只是应用反馈给程序员的一种结果现象,真正引发OOM的原因则需要程序员去定位、分析和解决。我们定位OOM的常用方法一般有以下几种:

  1. 利用日志定位OOM。

当Java程序发生OOM错误时,通常会在日志中输出相应的错误信息。例如:
在这里插入图片描述

在这个例子中,异常信息中指出了异常类型、异常代码位置、异常时间。在出现OOM错误前,Java程序通常会进行一系列的操作,可能会产生大量的对象或者导致内存使用量增加。因此,在分析日志时,需要对程序在出现OOM错误前的行为和状态进行分析,找出导致OOM错误的可能原因。该方法的局限性比较明显,仅能帮助我们快速确认是否真的发生了OOM错误,需要结合程序的行为和状态进行分析,对日志质量和代码熟悉度要求比较高,通常需要借助其他工具进行内存分析,以便更加准确地找出问题的根源并解决问题。

  1. 利用JDK自带命令定位OOM。

JDK自带命令是JDK提供的一系列命令行工具,用于监控、诊断和调优Java应用程序。这些工具广泛应用于Java程序的开发、测试、运维和排障过程中。常用的命令有jps、jstat、jmap等。
其中jstat是JDK自带的一个命令行工具,全称为 Java Virtual Machine statistics monitoring tool,可以用来监视和分析 Java 应用程序的内存使用和性能情况。jstat 命令可以显示有关 Java 堆和非堆内存使用情况、类加载、垃圾回收、线程和编译器等方面的信息。我们可以利用jstat -gcutil pid,我们可以通过该条命令获知内存使用和垃圾回收情况,计算出GC耗时和频率,以此来确认是否发生OOM。下图所示,几秒就发生一次Full GC,并且Full GC的平均耗时约为5秒,则说明该服务大概率出现OOM。
在这里插入图片描述

但是通过jstat命令还没有办法定位到具体问题,我们还需要借助jmap命令进一步分析。jmap -histo pid查看Java进程中各个类的实例数量和内存占用情况,可以通过这个选项查找内存泄漏的原因。如图所示,我们可以看到某个业务实例异常多,并且占用内存异常多,基本可以定位引发OOM的实例是该业务实例。
在这里插入图片描述

通过上图可以看到,com.example.LargeObject类占用了1亿字节的内存,是占用内存最多的对象。但是通过jmap还不能定位问题代码,我们可以通过jstack命令尝试定位问题代码。jstack命令可以用于查看Java进程中各个线程的状态和堆栈信息,结合jmap命令定位到的类型,查看最大概率发生OOM的问题代码。使用jstack pid | grep ‘LargeObject’如下所示,我们进一步怀疑问题代码行是LargeObject.java:23。
在这里插入图片描述

通过上面这个案例我们可得知使用JDK自带命令存在的好处:无需安装第三方工具:JDK自带了一些命令和工具,可以帮助开发人员和运维人员进行Java应用程序的诊断和优化;使用方便:JDK自带命令和工具使用方便,可以通过简单的命令和参数,快速获取Java应用程序的信息,定位和解决OOM问题。但是这种方法也存在一些弊端:自带命令对于程序员自身要求高,需要程序员掌握JVM相关知识,此外,JDK自带命令和工具功能和工具相对有限,可能无法满足一些高级诊断和优化需求;

  1. 利用第三方工具定位OOM。

Eclipse MAT(Memory Analyzer Tool)是一个用于分析Java堆转储文件的工具,可以用于查看Java进程中各个对象的实例数量、大小和引用关系等,进而找出导致OOM错误的对象和代码位置。
我们可以通过jmap -dump生成Java进程的内存快照文件,借助MAT分析dump文件,借此定位问题。打开dump文件后,首选查看Heap Dump Overview,在此页面我们可以看到堆的大概信息,包含堆使用大小、对象数量、类数量等,通过堆使用大小和服务应用内存配置对比判断内存使用情况,借此判断是否发生OOM。如果怀疑存在发生内存泄露的可能,然后打开Leak Suspects报告,查看潜在的内存泄露点。
在这里插入图片描述

通过该内存泄露报告,我们可以得知疑点一占用内存2.2G,实例类型和mysql相关,由此我们大概可以猜测出OOM的原因与查询语句有关。为了进一步验证我们的猜想,我们点击Details 查看疑点详情。在疑点详情页我们可以看到:疑点描述、对象最短依赖路径、线程详情等,我们重点关注线程详情中的线程栈信息,在线程栈中我们可以找到嫌疑最大的业务问题代码在XXXServiceImpl.java:673。
在这里插入图片描述

通过这个简单的例子,我们可以通过MAT分析dump文件,定位简单的OOM问题,当然,我们也可以通过Dominator tree、OQL等模块进一步印证自己的猜想。除MAT外,我们还可以使用Arthas定位OOM,但是Arthas需要在线上部署,才能对运行中的Java应用程序进行诊断和优化。这可能会对线上应用程序的性能和安全性产生一定的影响。
通过上面的案例,我们基本也可以得出使用第三方工具分析OOM有不少好处:第三方工具通常具有更多、更丰富的功能和工具,对程序员更友好,可以帮助程序员更快速、更准确地定位和解决OOM问题。但是第三方工具也有一定的局限性:第三方工具需要侵入应用程序环境,占用一定的资源,第三方工具也可能会涉及到敏感数据和信息,可能对程序运行产生不利影响。

4、关于OOM的一些思考?

OOM对程序的运行是极其负面的,面临OOM问题,我们要稳住自己的阵脚,在尽量不干预程序正常运行的前提下,选择合适的工具和方法收集数据,仔细分析和定位问题的根本原因,注意代码的优化和性能调优,进行合适的内存分配和回收,进行长期的监控和管理等措施,以确保应用程序的稳定性和可靠性。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

小红书2023“家生活”趋势白皮书

关于报告的所有内容,公众【营销人星球】获取下载查看 核心观点 近年来,年轻人与家的关系愈发紧密。 在小红书上,我们观察到了家居家装内容的蓬勃生长,3 年来相关内容的笔记规模增长了6倍,相关品类的搜索量增加的 3.…

【JavaEE初阶】了解JVM

文章目录 一. JVM内存区域划分二. JVM类加载机制2.1 类加载整体流程2.2 类加载的时机2.3 双亲委派模型(经典) 三. JVM垃圾回收机制(GC)3.1 GC实际工作过程3.1.1 找到垃圾/判定垃圾1. 引用计数(不是java的做法,Python/PHP)2. 可达性分析(Java的做法) 3.1.2 清理垃圾1. 标记清除2…

自学(黑客)技术,入门到入狱!

1.网络安全是什么 网络安全可以基于攻击和防御视角来分类,我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术,而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 2.网络安全市场 一、是市场需求量高; 二、则是发展相对成熟入…

@ControllerAdvice注解使用及原理探究 | 京东物流技术团队

最近在新项目的开发过程中,遇到了个问题,需要将一些异常的业务流程返回给前端,需要提供给前端不同的响应码,前端再在次基础上做提示语言的国际化适配。这些异常流程涉及业务层和控制层的各个地方,如果每个地方都写一些…

Typescript中的元组与数组的区别

Typescript中的元组与数组的区别 元组可以应用在经纬度这样明确固定长度和类型的场景下 //元组和数组类似,但是类型注解时会不一样//元组赋值的类型、位置、个数需要和定义的类型、位置、个数完全一致,不然会报错。 // 数组 某个位置的值可以是注解中的…

正点原子HAL库入门1~GPIO

探索者F407ZGT6(V3) 理论基础 IO端口基本结构 F4/F7/H7系列的IO端口 F1在输出模式,禁止使用内部上下拉 F4/F7/H7在输出模式,可以使用内部上下拉不同系列IO翻转速度不同 F1系列的IO端口 施密特触发器:将非标准方波,整形为方波 当…

01-序言

文章作者:里海 来源网站:https://blog.csdn.net/WangPaiFeiXingYuan 简介: 此专栏是学习“线性代数”课程做的笔记,教程来自B站。视频作者是Grant Sanderson, 这套视频里的动画是他通过manim制作的(manim是…

怎么维护好自己的电脑

你的电脑已经成为你工作、学习、娱乐的最佳工具之一,但是如果你不做好电脑维护工作,就可能面临着电脑变慢、蓝屏、崩溃等问题。在这篇文章中,我们将介绍10个电脑维护步骤,让你的电脑更加稳定! 为什么需要电脑维护&…

python数据处理程序代码,如何用python处理数据

大家好,给大家分享一下python数据处理程序代码,很多人还不知道这一点。下面详细解释一下。现在让我们来看看! 要求:分别以james,julie,mikey,sarah四个学生的名字建立文本文件,分别存…

285 · 高楼大厦

链接:LintCode 炼码 - ChatGPT!更高效的学习体验! 题解: 1.从左往右维护一个单调递减,栈的长度就是,可以看到最多的高楼 2.从右往后也是维护一个单调递减的栈 class Solution { public:/*** param arr:…

Java判断文件的系统格式编码格式

使用Java判断一个文件的系统格式(亲测可用),比如我们常见的Windows格式的文件,Unixg格式的文件,Mac格式的文件;常常有这样的场景:我们在Windows系统编写的脚步上传到Linux系统执行,执…

【验证测试】未初始化的全局变量和局部变量的初值

验证目标&#xff1a; 未初始化的全局变量的初值为 0未初始化的局部变量的初值为随机值 测试用例&#xff1a; #include <stdio.h>char gval1; int gval2; static long gval3;int main() {unsigned char uchTmp1;unsigned int uTmp2;printf("%d\n", gval1)…

Centos虚拟机忘记密码-修改密码

1.重启系统 2.在这个选择界面&#xff0c;按e建 3.找到如下位置&#xff0c;插入init/bin/sh 4.填写完成后按Ctrlx引导启动 5.输入mount -o remount, rw / (注意空格) 6.重置密码 出现以下为重置成功 7.执行touch /.autorelabel 8.退出exec /sbin/init 9.输入你的新密…

14-4_Qt 5.9 C++开发指南_QUdpSocket实现 UDP 通信_UDP组播

文章目录 1. UDP组播的特性2. UDP 组播实例程序的功能3. 组播功能的程序实现4. 源码4.1 可视化UI设计4.2 mainwindow.h4.3 mainwindow.cpp 1. UDP组播的特性 下图简单表示了组播的原理。UDP 组播是主机之间“一对一组”的通信模式&#xff0c;当多个客户端加入由一个组播地址定…

STM32——STM32F401x系列标准库的下载+环境搭建+建工程步骤(更完整)

文章目录 标准库的下载环境搭建建工程最后的话 标准库的下载 1.STM32标准库的官网下载网站https://www.st.com/content/st_com/en.html 2. 3. 4. 5. 6. 7.点击之后下滑 8.选择自己需要的版本下载 环境搭建建工程 大致步骤同之前我写的一篇STM32——建工程差不多&#xff0…

快速WordPress个人博客并内网穿透发布到互联网

快速WordPress个人博客并内网穿透发布到互联网 文章目录 快速WordPress个人博客并内网穿透发布到互联网 我们能够通过cpolar完整的搭建起一个属于自己的网站&#xff0c;并且通过cpolar建立的数据隧道&#xff0c;从而让我们存放在本地电脑上的网站&#xff0c;能够为公众互联网…

jenkins准备

回到目录 jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具&#xff0c;主要用于持续、自动的构建/测试软件项目、监控外部任务的运行。Jenkins用Java语言编写&#xff0c;可在Tomcat等流行的servlet容器中运行&#xff0c;也可独立运行。通常与版本管理工具(SCM)、构…

【每日易题】数据结构链表篇——单链表oj题(1),几道典型例题带你快速掌握单链表

君兮_的个人主页 勤时当勉励 岁月不待人 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;今天来填一个埋了好久的坑&#xff0c;在暑假之前就预告过这个系列&#xff0c;但由于各种原因&#xff08;主要是有点懒&#xff09;今天才开坑。我们这个系列主要是…

Scratch 之 如何制作简单的碰撞箱

hello&#xff0c;大家好&#xff0c;今天教给大家如何制作粗糙的碰撞箱 本次教学不用拓展、不用自制积木、不用变量、不用列表 首先明确原理 图1 我们想做到第一个 而大家不要做成第二个 错误示范&#xff1a; 然后就变成了 咳咳咳 这就是我们不想看到的 于是你可以这样…

ESP32-C2开发板 ESP8684芯片 兼容ESP32-C3开发

C2是一个芯片采用4毫米x 4毫米封装&#xff0c;与272 kB内存。它运行框架&#xff0c;例如ESP-Jumpstart和ESP造雨者&#xff0c;同时它也运行ESP-IDF。ESP-IDF是Espressif面向嵌入式物联网设备的开源实时操作系统&#xff0c;受到了全球用户的信赖。它由支持Espressif以及所有…