JVM实战(33)——内存溢出之内存使用率过高

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析

阶段4、深入jdk其余源码解析

阶段5、深入jvm源码解析

一、简介

本章,我们将讲解一个已经稳定运行的系统的内存溢出问题,该内存溢出问题的元凶是类加载器,我们先来看下系统的背景。

1.1 系统背景

这个系统已经在线上稳定运行了一段时间,部署在Tomcat中启动。突然有一天收到告警,显示许多访问该系统的调用请求出现假死现象,但是过了一会儿又可以了。经过排查发现,每隔一段时间,系统就会出现假死。

一般来说,系统出现假死,接口无法调用,就是系统的资源不足以处理新的请求,所以我们先通过top命令排查下机器的CPU和内存使用情况。

  • 如果这个服务大量使用了内存,导致频繁Full GC(这个问题我们之前的章节介绍过),从而引发STW,接口调用就会出现假死现象。
  • 如果机器的CPU负载太高,比如某个进程耗尽了CPU资源,那么正常服务就始终无法得到CPU去执行,这也可能导致假死。

我们通过top命令发现,系统本身对CPU消耗非常少,也就1%,但是却耗费了50%的总内存。要知道,机器配置是4核8G,我们给JVM进程分配的总内存最多也就是4-5G,系统消耗了4-5G的内存,说明JVM中的Java堆内存几乎被占满。

二、问题分析

2.1 内存使用率过高

我们先分析下,进程占用内存过高会导致什么,一般会发生三种情况:

  1. 频繁Full GC,GC带来的Stop the World导致程序假死;
  2. 内存占用过多,引起内存溢出;
  3. 内存使用率过高,导致程序进程因为申请内存不足,直接被操作系统给干掉。

我们先用jstat分析下GC情况,发现确实经常发生GC,但是每次GC耗时也就几百毫秒,程序也没有因此出现假死现象。

我们再排查是否发生了OOM,经过日志分析,程序并没有抛出任何OOM异常。那只有第三种情况了,可能是程序进程被OS杀掉,然后由于自启脚本又重新启动了,但是在这段时间内,程序无法被访问,就出现了假死的现象。

2.2 JVM参数不合理

我们通过MAT分析dump出的内存快照,发现有一大堆的ClassLoader占用超过了50%的内存。最后,根据MAT层层抽丝剥茧,发现是写这个代码的童鞋搞了个自定义的类加载器,但是代码中无限制的创建了大量的自定义类加载器,重复加载了大量数据,结果一下子把内存耗尽了,导致程序进程被OS杀掉。

三、系统优化

优化方式很明显,就是修改有问题的代码点,避免重复创建自定义的类加载器,避免重复加载大量数据到内存中。

四、总结

本章介绍的案例和之前有点区别,程序其实并没有发生OOM异常,但又确实是因为内存占用过多而被OS杀死。这个案例告诉大家,无论如何优化分析,它们背后的原理都是一套东西,掌握分析问题的思路才是最重要的。

相关推荐

  1. JVM实战33)——内存溢出内存使用率

    2024-01-26 22:22:02       59 阅读
  2. JVM实战(27)——内存溢出概述

    2024-01-26 22:22:02       62 阅读
  3. JVM实战(29)——模拟栈内存溢出

    2024-01-26 22:22:02       55 阅读
  4. JVM内存溢出排查

    2024-01-26 22:22:02       43 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-26 22:22:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-26 22:22:02       101 阅读
  3. 在Django里面运行非项目文件

    2024-01-26 22:22:02       82 阅读
  4. Python语言-面向对象

    2024-01-26 22:22:02       91 阅读

热门阅读

  1. 三、详解Redis分布式锁&Redisson分布式锁

    2024-01-26 22:22:02       58 阅读
  2. 本人原创写的用PHPps支付宝支付凭证截图的源码

    2024-01-26 22:22:02       45 阅读
  3. apt-mark详解

    2024-01-26 22:22:02       49 阅读
  4. 动态链接和静态链接及交叉编译的思考

    2024-01-26 22:22:02       52 阅读
  5. 015vue

    2024-01-26 22:22:02       57 阅读
  6. yum找不到 mysql-server

    2024-01-26 22:22:02       46 阅读