首页 > 系统相关 >JVM内存溢出问题排查

JVM内存溢出问题排查

时间:2022-09-28 16:05:57浏览次数:51  
标签:文件 dump 排查 线程 内存 JVM 占用率 溢出

内存溢出 out of memory : 通俗理解就是内存不够用了,是我们工作当中经常会遇到的问题,内存溢出有可能发生在正常的情况下,而非代码层面问题导致,比如高并发下,大量的请求占用内存,垃圾回收机制无法进行回收,而导致的内存溢出,这种情况就需要我们去调整架构了。一但出现内存溢出问题,我们需要快速定位并解决,尤其是生产环境,所以针对内存溢出问题,我们需要掌握一些常用的排查工具,针对不同场景、现象有快速排查思路。引起内存溢出的原因有很多种,常见的有以下几种:

● 内存中加载的数据量过于庞大,如一次从数据库取出过多数据;

● 资源使用之后没有及时关闭,导致对象无法被GC回收;

● 代码中存在死循环或循环产生过多重复的对象实体;

● 使用的第三方软件中的BUG;

● 启动参数内存值设定的过小;

排查辅助技术介绍

01

排查内存问题的常用命令:

● Jps:是java提供的一个显示当前所有java进程pid的命令

JVM内存溢出问题排查_内存溢出

● Jstat 命令:查看堆内存各部分的使用量,加载类的数量以及GC的情况

JVM内存溢出问题排查_重启_02

● Jstack命令:主要是用来查看java线程的堆栈信息,分析线程有没有死锁,比如下面的这个两个线程互相等待对方释放锁而产生的死锁信息

JVM内存溢出问题排查_内存溢出_03

● Jmap:主要是用来dump java进程内存快照的,便于我们去分析内存中对象的存储情况

02

内存文件分析工具:

● MemoryAnalyzer:这是一款Eclipse提供的内存分析工具,可以结合Eclipse使用,也可独立使用

● JProfiler,:这是由ej-technologies GmbH公司开发的一款内存分析工具,可以结合IDEA使用

● Jconsole:是一个用java写的GUI程序,用来监控VM,并可监控远程的VM

案例说明

正常情况下,我们生产环境都会配置监控措施,服务器资源比如CPU、内存的使用达到我们预设的报警阈值,就会触发报警,提示我们相应的维护人员,这时我们开发人员就需要快速定位原因,采取相应措施。下面结合我之前的一个例子来说下:

1.一天晚上19点30左右线上32服务器开始持续出现cpu占用率高的现象,最高已达到90%左右,同时伴随的其他现象还有内存占用率稍高,达到60%左右,因为当时监控配置的是机器的监控,并没有直接收到java服务内存溢出的报警,所以当时是从cpu异常开始排查。

2.收到报警后,第一感觉存在代码死循环,或者请求线程太多。但这个时间点请求量很少,也没有修改过代码。

3.cpu占用率高基本和进程/线程有关,使用top查看一下cpu占用率高的进程,进程id是18713

JVM内存溢出问题排查_重启_04

18713正是系统的跑批服务器,查看日志发现19:30左右执行了上传文件到oss服务器的批量任务,查看日志发现在下午执行了20几次

4.使用top -H -p 18713查看cpu占用率高的线程,存在4个

JVM内存溢出问题排查_测试_05

5.将这四个线程的线程id转换成16进制打印,分别是4922,4923,4924,4925

JVM内存溢出问题排查_测试_06

6.使用jstack -l 18713>> a.txt进行线程dump,如有必要可以多输出几次。根据上面4个线程的线程id在文件中查找,找到4条线程日志

JVM内存溢出问题排查_java_07

注意这四个线程是jvm垃圾回收线程,不是业务线程。

7.接着使用jstat -gc 18713 5000打印垃圾回收日志进行确认,发现jvm很短时间内进行了多次的fullgc操作

JVM内存溢出问题排查_测试_08

8.此时基本确定存在垃圾回收问题,只是还没有导致内存溢出,虽然线上配置了jvm溢出之后进行内存dump,但此时内存占用只有60%。

JVM内存溢出问题排查_内存溢出_09

9.只能使用jmap -dump:file=dump.hprof 18713强制进行一次内存dump。导出文件到本地目录,文件通常会很大。所以建议jvm堆内存上限不要设置的太大。否则内存分析工具分析也成问题。

  1. 下载MemoryAnalyzer内存分析工具,其他工具也可以。配置下MemoryAnalyzer.ini文件,将内存调的大一点,否则无法进行分析。

JVM内存溢出问题排查_测试_10

  1. 导入dump文件,时间稍长,慢慢等待。导入后有各种详细的展示视图。比如大对象,数量多的对象,泄露猜测等。

JVM内存溢出问题排查_重启_11

  1. 发现占用内存90%多的是http连接对象,点击查询引用明细,发现是oss依赖库引用了大量http连接对象

JVM内存溢出问题排查_java_12

  1. 结合19:30左右的批量执行情况推断,这个批量存在内存泄露,使用后没有及时释放连接,造成内存占用率高,而垃圾回收在回收这部分内存的时候又造成了cpu占用率高。这次跑批的次数有点多。
  2. 排查代码发现果然如此:ossClient对象使用后没有关闭

JVM内存溢出问题排查_内存溢出_13

  1. 修复代码之后,再次重启跑批,发现问题也得到了解决。

总结

当然,分析和解决内存溢出相关问题的步骤,不是固定的,还需要根据实际情况去做调整,止损是第一位的,正常情况我们需要快速重启的先,重启可以使服务快速恢复,但是只重启,指标不治本,如果没有定位到溢出的原因,重启一段时间可能又会溢出。所以一定要留存排查依据,比如内存文件,线程的文件等。留存内存文件有两种方式:一是配置jvm启动参数: -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=xxxx(文件导出路径),JVM发生OOM时,自动生成dump文件;二是采用jmap命令,手动进行内存dump。

标签:文件,dump,排查,线程,内存,JVM,占用率,溢出
From: https://blog.51cto.com/u_15649298/5719632

相关文章

  • 数据库问题排查
    数据库若干查询语句记录 ##连接某个数据库mysql-hdbip-uusername-ppassword##进入某个数据库usehenry;##显示若干表showtables;##查询锁的......
  • 如何划分与组织内存(上)?
    1)本节我们要接触内存了,那我们用最通俗的语言来类比操作系统和内存的关系应该是怎样的?操作系统是政府,内存是土地。政府必须合理规划好土地,人民才能安居乐业。2)既然要规划内存......
  • 反射(类加载内存分析)
    java内存图:  类的加载过程: 加载:  将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后生成一个代表这个类的java.lang.Class对象链......
  • JVM调优
      下面是跟可大算法  打击清除的三种算法:   Mark-Sweep标记法缺点:内存碎片化,--这样就装不下大的对象了;   Copying算法--一分为二  ......
  • 惊!ThreadLocal你怎么动不动就内存泄漏?
    “今天无聊带大家分析下ThreadLocal为什么会内存泄漏~前言使用ThreadLocal不当可能会导致内存泄露,是什么原因导致的内存泄漏呢?正文我们首先看一个例子,代码如下:pub......
  • 驱动开发:内核CR3切换读写内存
    首先CR3是什么,CR3是一个寄存器,该寄存器内保存有页目录表物理地址(PDBR地址),其实CR3内部存放的就是页目录表的内存基地址,运用CR3切换可实现对特定进程内存地址的强制读写操作......
  • Java多线程内存读写 —— 内存屏障的理解
    在现代计算机中,CPU往往都是多核的,而由于每个CPUCore中都有自己的高速缓存Cache,因此就会造成内存数据读写的不一致性,表现为 ​​指令乱序​​​ 与 ​​不可见性​​​ ......
  • 【elk】es限制内存
    https://www.jianshu.com/p/aa450daecec0  找到ES的安装目录,然后找到config文件夹,里面都是相关的配置文件。  其中,jvm.options可以修改es运行时候的内......
  • 4G内存可以用来做什么
    https://zhidao.baidu.com/question/1894866553066998500.html如果主要用于一般的文档编辑、网页浏览和音频、视频播放,4G内存基本能够满足。而如果电脑主要用于图片处理、......
  • 内存回收、流程控制和循环
    垃圾回收机制"""有一些语言内存空间的申请和释放都需要程序员自己写代码才可以完成但是python却不需要通过垃圾回收机制自动管理"""1.引用计数name='jason'......