JVM 线上问题定位实战(CPU 飙升)

本文通过一个实战案例介绍了如何定位和解决JVM线上问题,特别是CPU占用过高和内存飙升的情况。通过`top`命令监控、JDK性能诊断工具如`jstack`和`jmap`,分析了CPU飙升是由垃圾回收线程导致,而内存占用过高则由内存泄漏引起。最后,总结了内存泄漏和内存溢出的区别,以及优化思路。
摘要由CSDN通过智能技术生成

问题描述

很多时候我们的系统在使用过程中经常出现卡顿的情况,或者请求变慢(延迟高)等等情况,然后运维人员跑来给你说写的什么垃圾代码,CPU 飙升,经常 100%,内存飙升。

如果你不知道怎么定位问题,觉得自己代码也找不出什么问题,那就说重启试试咯!!!

当然了,这种处理方式可以解决,但并不能从根本上解决问题,试想一下如果对于高并发的系统,你重启项目肯定是不行的,所以我们要找到问题的源头,因为我们程序都是跑在 JVM 里面的,所以上面的 2 种情况很可能是我们的代码出现了问题,比如常见的死循环,递归等等,当然这种就是比较明显的错误。大多数情况下我们能察觉出来,而对于比较难以察觉的代码问题,则需要我们在 JVM 的层面去解决,也就是所谓的 JVM 调优

问题如下:

  1. 系统 CPU 经常 100%,如何调优?

  2. 系统内存飙升,如何定位问题?

当然,有人会说,加内存,加服务器等等,我们要理解调优的目的,其目的是为了利用现有的内存来获取高吞吐量或者低延迟,说白了就是花更少的钱做更多的事。

场景模拟

之前在公司做过一个差旅系统(类似携程,但针对的是企业用户),大概意思是年终要定时统计年终的差旅费用,包括机票,酒店费用报销等等,把数据从 MySQL 中取出来计算汇总,如下:

大概步骤:

  1. 从数据库中批量读取用户信息;

  2. 利用线程池多线程执行任务计算。

代码如下:

/** * VM参数: -XX:+PrintGC -Xms200M -Xmx200M * GC调优---生产服务器推荐开启(默认是关闭的) * -XX:+HeapDumpOnOutOfMemoryError */public class FullGCProblem {
      //线程池    private static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(50, new ThreadPoolExecutor.DiscardOldestPolicy());
    public static void main(String[] args) throws Exception {
          //50个线程        executor.setMaximumPoolSize(50);        while (true) {
              calc();            // 休眠 100ms 模拟计算耗时            Thread.sleep(100);        }    }
    /**     * 模拟多线程执行任务计算     */    private static void calc() {
          List<UserInfo> taskList = getAllCardInfo();        taskList.forEach(userInfo -> {
              executor.scheduleWithFixedDelay(() -> {
                  userInfo.other();            }, 2, 3, TimeUnit.SECONDS);        });
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值