JVM实战系列之CPU100%和内存100%排查

 更新时间:2023年06月05日 09:31:12   作者:互联网小趴菜  
本文主要介绍了JVM实战系列之CPU100%和内存100%排查,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

1. 基础概念

  • 内存溢出(Memory Overflow)指的是程序在申请内存时,向操作系统申请了一块内存空间,但由于某种原因(如程序错误、缺乏足够的内存等),导致程序使用的内存超过了申请到的内存大小。这会导致程序崩溃或者出现未定义的行为。
  • 内存泄漏(Memory Leak)指的是程序在动态分配内存后,没有及时释放已经不需要的内存空间,导致系统中存在大量无用的内存占用,最终可能会导致系统的性能下降或者耗尽可用内存资源。

可以这样理解:内存溢出是指程序需要的内存超过了可用内存;而内存泄漏则是指程序本身的内存管理不当,使用了系统提供的内存却没有及时释放。

2. 内存100%案例

堆内存溢出代码示例:

private static List<byte[]> CACHE = new ArrayList<>(1000);
@GetMapping("/tuningTest")
public String tuningTest(){
    for (int loopTimes = 1; loopTimes < 20; loopTimes++) {
        long cacheSize = ObjectSizeCalculator.getObjectSize(CACHE);
        LOGGER.info("第 {} 次循环前, 对象已占用 {} M 内存", loopTimes, cacheSize / 1024 / 1024);
        // 每次占用5M内存
        CACHE.add(new byte[5 * 1024 * 1024]);
    }
    return "OK";
}

启动参数:java -jar -Xms32m -Xmx64m -XX:PermSize=15M -XX:MaxPermSize=30M jvmtest-0.0.1-SNAPSHOT.jar

测试时为了效果明显可以用压测工具,并发数20,轮次1000。更有助于分析问题

2.1 top 命令查看cpu和内存情况

2.2 jmap -heap PID查看jvm内存使用情况

从图中可以看出老年区的内存使用率已经达到了96%

2.3 jstat -gc PID 查看GC的情况

  • YGC : YG GC的次数
  • YGCT:YG GC的平均时间
  • FGC: FULL GC的次数
  • FGCT:FULL GC的平均时间

这里可以连续看几次就会发现FULL GC的次数在疯狂增长,而且FULL GC的平均时间也会增长,这就是CPU100%的原因,因为CPU一直在尝试垃圾回收

2.4 jmap -dump:format=b,file=./jmap_dump.hprof PID 使用jmap命令生成分析所需要用的dump文件。

使用Jprofiler打开(为什么不用mat,因为我没安装上,不知道为啥)

如上图已经定位出来了问题,这个工具还是很好用的,有兴趣的大佬们可以研究研究

3. CPU100%案例

代码示例

/**
 * 死循环
 *
 * @return
 */
@RequestMapping("/deadCycle")
public String deadCycle() {
    for (int i = 1; i > 0; i++) {
        System.out.println(i);
    }
    return "Success";
}
/**
 * 死锁
 *
 * @return
 */
@RequestMapping("/deadLock")
public String deadLock() {
    Lock lock1 = new ReentrantLock();
    //线程t1中
    new Thread(() -> {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        while (!lock1.tryLock()) {
            System.out.println("线程1 一直自旋获取锁");
        }
        System.out.println("线程1 获取到锁 do something");
    }).start();
    // 线程2
    new Thread(() -> {
        lock1.lock();  //此时线程2 获取到锁 但是一直阻塞 导致锁无法释放
        while (true) {
        }
    }).start();
    return "Success";
}

这里就整一个最简单里例子,目的就是为了让CPU一直在运算。

3.1 top 命令查看CPU占用100%的进程号

3.2 top -H -n 1 -p PID 然后通过命令查找对应进程下线程的状态

3.3 然后通过 jstack -l PID > ./jstack.log 命令输出进程的线程文件

jstack.log的文件PID是十六机制,从3.2步骤中我们可以看出PID为25778的线程CPU特别高,25778二机制为0x64b2。拿到16进制去文件里搜索能够很明确看出哪里出现了问题

到此这篇关于JVM实战系列之CPU100%和内存100%排查的文章就介绍到这了,更多相关JVM CPU100%和内存100%排查内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 关于JVM翻越内存管理的墙

    关于JVM翻越内存管理的墙

    这篇文章主要介绍了JVM翻越内存管理的墙,由虚拟机管理内存看起来一切都很美好,但也正是因为把控制内存的权力交给了Java虚拟机,一旦出现内存泄漏和溢出方面的问题,就不得不从Java虚拟机角度上去排查问题,本文给大家介绍的非常详细,需要的朋友可以参考下
    2022-05-05
  • SpringMVC拦截器零基础掌握

    SpringMVC拦截器零基础掌握

    拦截器(Interceptor)是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行。本文将详细讲讲SpringMVC中拦截器的概念及入门案例,感兴趣的可以尝试一下
    2023-03-03
  • SpringBoot中的异步执行方法详解

    SpringBoot中的异步执行方法详解

    这篇文章主要介绍了SpringBoot中的异步执行方法详解,ThreadpoolTaskExecutor不需要手动的创建当前线程池,但往往我们还是会手动指定,具体原因看源码就可以自有判断,需要的朋友可以参考下
    2023-10-10
  • SpringBoot中的Bean注入问题

    SpringBoot中的Bean注入问题

    SpringBoot开发中,Bean注入是关键,涉及构造函数注入、Setter注入和字段注入等方法,常见问题包括Bean未找到、循环依赖、多个实现注入等,推荐使用构造函数注入以增强代码测试性和维护性,并关注Bean的生命周期和作用域
    2024-09-09
  • java调用process线程阻塞问题的解决

    java调用process线程阻塞问题的解决

    这篇文章主要介绍了java调用process线程阻塞问题的解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • Java 定时器(Timer)及线程池里使用定时器实例代码

    Java 定时器(Timer)及线程池里使用定时器实例代码

    这篇文章主要介绍了Java 定时器(Timer)及线程池里使用定时器实例代码的相关资料,需要的朋友可以参考下
    2016-12-12
  • java正则表达式表单验证类工具类(验证邮箱、手机号码、qq号码等)

    java正则表达式表单验证类工具类(验证邮箱、手机号码、qq号码等)

    这篇文章主要介绍了java使用正则表达式进行表单验证工具类,可以验证邮箱、手机号码、qq号码等方法,需要的朋友可以参考下
    2014-04-04
  • 快速解决Hash碰撞冲突的方法小结

    快速解决Hash碰撞冲突的方法小结

    这篇文章主要介绍了快速解决Hash碰撞冲突的方法小结,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • Maven项目如何在pom文件中引入lib下的第三方jar包并打包进去

    Maven项目如何在pom文件中引入lib下的第三方jar包并打包进去

    在使用Maven进行项目开发时,引入第三方私有的Jar包可能会遇到问题,一种常见的解决方案是将Jar包添加到项目的lib目录,并通过IDE进行配置,但这需要每个开发者单独操作,效率低下,更好的方法是通过Maven的pom.xml文件管理这些Jar包
    2024-09-09
  • Java版数据结构插入数据时遇到的结点为空的问题详解

    Java版数据结构插入数据时遇到的结点为空的问题详解

    这篇文章主要介绍了Java版数据结构插入数据时遇到的结点为空的问题及解决办法,需要的朋友们可以学习下。
    2019-09-09

最新评论