内存爆炸、CPU100%问题定位

news2024/11/13 3:46:53

目录

  • 一、内存爆炸相关
    • 1、关于-Xms(最小堆内存)和-Xmx(最大堆内存)
    • 2、JVM初始化时申请实际物理内存
    • 3、OutOfMemory问题排查
      • (1) 堆内存溢出排查
      • (2) 堆外内存溢出排查
  • 二、CPU 100及死锁问题定位
    • 1、CPU 100问题排查
      • (1) 找到程序对应进程号
      • (2) 查找进程对应的线程编号
      • (3)查看线程堆栈信息
    • 2、死锁问题排查

一、内存爆炸相关

1、关于-Xms(最小堆内存)和-Xmx(最大堆内存)

最大堆内存为JVM能向操作系统申请的最大内存。最小堆内存并不是程序一启动就申请这么多内存,而是当前进程如果申请的内存已超过最小堆内存,内存回收时,大于最小堆内存的部分会返回给操作系统,其它申请的内存不会。

2、JVM初始化时申请实际物理内存

默认没有配置-XX:+AlwaysPreTouch参数时,JVM进程申请的内存只是虚拟内存,程序运行时根据虚拟内存地址映射到实际的物理内存,缺页时才将数据加载到物理内存,分配实际的物理空间。加上-XX:+AlwaysPreTouch参数后,程序将直接分配到实际的物理内存,而不是根据需要在缺页时才申请物理内存。

简单来说就是没有开启预热时,JVM只是向操作系统做了登记,告诉操作系统我需要多少内存,但实际上并没有进行物理分配,加上该参数后在程序启动时就会分配物理内存。

注意:加上该参数可能会导致程序启动变慢。

3、OutOfMemory问题排查

(1) 堆内存溢出排查

内存溢出示例如下:

/**
 * -Xmx512m -server -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:\Users\Administrator\Desktop\java_heapdump.hprof
 */
public class OutOfMemoryExample1 {

 private static List<Object> space = new ArrayList<>();

 public static void main(String[] args) throws Exception {
  // 内存泄漏 最终会导致 = 内存溢出
  for (int i = 0; i < 1000; i++) {
   space.add(new byte[1024 * 1024 * 128]);
   Thread.sleep(3000L);
  }
 }
}

通过MAT(Eclipse Memory Analyzer)工具查找leak suspect即可排查:

在这里插入图片描述

(2) 堆外内存溢出排查

直接内存溢出示例:

/**
 * 堆外内存溢出
 * 控制堆外内存大小:-XX:MaxDirectMemorySize=128m -XX:+HeapDumpOnOutOfMemoryError
 */
public class OutOfMemoryExample2 {

 private static List<Object> space = new ArrayList<>();

 public static void main(String[] args) throws Exception {
  // 内存泄漏 最终会导致  内存溢出
  for (int i = 0; i < 1000; i++) {
   ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1024 * 1024 * 64);
   byteBuffer.put(new byte[1024 * 1024 * 5]);
   space.add(byteBuffer);
   Thread.sleep(2000L);
  }
 }
}

对于堆外内存溢出的情况,通过jvisualvm中的btrace插件分析调用情况,如下:
在这里插入图片描述


二、CPU 100及死锁问题定位

1、CPU 100问题排查

CPU占用率过高通常是因为死循环或者递归调用导致的,通过jstack基本能定位到具体是哪些线程在执行CPU高度密集型操作。示例代码如下:

public class Cpu100Example {

 public static void main(String[] args) {
  System.out.println("Starting executing the programme");
  // 如果有多核,开启与逻辑cpu相等的线程数执行计算型任务即可,不要有阻塞或者I/O操作
  while (true) {
   new Random().nextInt();
  }
 }
}

问题解决思路如下:

(1) 找到程序对应进程号

通过jps或者jcmd命令可查到程序进程号,如下:

[universe@VM_0_13_centos ~]$ jps -l
2792 org.apache.zookeeper.server.quorum.QuorumPeerMain
2745 org.apache.zookeeper.server.quorum.QuorumPeerMain
30858 com.netease.issue.cpu.Cpu100Example
2716 org.apache.zookeeper.server.quorum.QuorumPeerMain
31822 sun.tools.jps.Jps

(2) 查找进程对应的线程编号

top -H -p 30858

结果如下:
在这里插入图片描述
从上图可以看到,pid为30859的线程几乎占用了全部CPU。

(3)查看线程堆栈信息

jstack命令内容中的nid为上一步我们获取到的线程pid的16进制形式,因此先把线程pid转换为16进制,再对jstack内容进行查找。

在这里插入图片描述
现在可以看到该线程的方法调用栈,进而找到相应的代码。

2、死锁问题排查

示例代码如下:

public class DeadLockExample {

 private static Object monitor1 = new Object();

 private static Object monitor2 = new Object();

 public static void main(String[] args) {
  new Thread(new ObtainLockTask1()).start();
  new Thread(new ObtainLockTask2()).start();
 }

 private static class ObtainLockTask1 implements Runnable {

  @Override
  public void run() {
   System.out.println(Thread.currentThread().getName() + " starts to obtain lock from monitor1");
   try {
    while (true) {
     synchronized (monitor1) {
      System.out.println(Thread.currentThread().getName() + " has obtained lock from monitor1");
      Thread.sleep(3000);
      synchronized (monitor2) {
       System.out.println(Thread.currentThread().getName() + " starts to obtain lock from monitor2");
      }
     }
    }
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
 }

 private static class ObtainLockTask2 implements Runnable {

  @Override
  public void run() {
   System.out.println(Thread.currentThread().getName() + " starts to obtain lock from monitor2");
   try {
    while (true) {
     synchronized (monitor2) {
      System.out.println(Thread.currentThread().getName() + " has obtained lock from monitor2");
      Thread.sleep(3000);
      synchronized (monitor1) {
       System.out.println(Thread.currentThread().getName() + " starts to obtain lock from monitor1");
      }
     }
    }
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
 }
}

依然通过jstack命令查看线程堆栈信息可以定位,如下图:
在这里插入图片描述

注意:通过synchronized关键字导致的Java平台级死锁通过jstack命令可以直接分析出来,而使用ReentrantLock导致的死锁则不能。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

根据Excel表格数据去修改数据库数据

一、背景 项目上线&#xff0c;实施任务发来一份Excel表格数据 需要将供应商和生产厂商进行绑定&#xff0c;因为数据过多&#xff0c;实施人员一个个绑定时间成本过高&#xff0c;想让开发给出一个脚本。 二、操作 比如这些数据 生产厂商为A 供应商为B 以update 语句为例 …

基于Vertx实现可配置及可扩展的IOT服务

搭建框架的目标 相信写过IOT服务的伙伴应该知道&#xff0c;面对各种千奇百怪的通信协议&#xff0c;特别是16进制报文的协议&#xff0c;有些协议看的确实有点让人头疼。但这些协议中也有很多共性&#xff0c;不必针对每过协议都把一些业务无关的代码再撸一遍。 搭建这个项目主…

【Javascript】‘var‘ is used instead of ‘let‘ or ‘const‘

解决&#xff1a; 设置完之后,var 就不会再出现黄色波浪线警告

普通二维码跳转微信小程序实战

简介 服务端springboot项目,前端基于uniapp的微信小程序,要求扫描二维码之后进入到小程序指定页面,下面记录一下实现过程以及过程中遇到的问题. 实现过程 下面是成功跳转的配置截图: 首先说下二维码规则,这个地方需要填写扫描二维码之后打开的地址,这个地址在我的项目里…

Keil实现Flash升级跳转(STM32/GD32/HC32)

编写BOOT程序&#xff0c;和APP程序。 BOOT程序检查OTA参数&#xff0c;执行OTA升级&#xff0c;然后跳转到APP代码。 记录一下跳转APP需要修改得东西&#xff1a; 1、BOOT程序 修改跳转地址 先检查APP地址是否有效 然后关闭外设 反初始化 设置MSP指针&#xff0c;进行跳转 …

多商户自营连锁小程序商城的作用是什么

近几年&#xff0c;线上线下经营压力很大&#xff0c;不少商家都希望通过数字化转型实现破局或增长&#xff0c;单店管理力度相对容易些&#xff0c;但如果是连锁门店&#xff0c;近几年则相对风险大些&#xff0c;但从2020年至今依然有不少品牌选择扩店&#xff0c;增加连锁规…

vue 组件封装 综合案例

vue 组件封装 综合案例 **创建 工程&#xff1a; H:\java_work\java_springboot\vue_study ctrl按住不放 右键 悬着 powershell H:\java_work\java_springboot\js_study\Vue2_3入门到实战-配套资料\01-随堂代码素材\day05\准备代码\11-综合案例-商品列表 vue --version vue c…

深入探索Sharding JDBC:分库分表的利器

随着互联网应用的不断发展和用户量的不断增加&#xff0c;传统的数据库在应对高并发和大数据量的场景下面临着巨大的挑战。为了解决这一问题&#xff0c;分库分表成为了一个非常流行的方案。分库分表主流的技术包括MyCat和Sharding JDBC。我们来通过一张图来了解这两者有什么区…

38 WEB漏洞-反序列化之PHPJAVA全解(下)

目录 Java中的API实现序列化和反序列化演示案例WebGoat_Javaweb靶场反序列化测试2020-网鼎杯-朱雀组-Web-think java真题复现 文章参考&#xff1a; https://www.cnblogs.com/zhengna/p/15737517.html https://blog.csdn.net/MCTSOG/article/details/123819548 ysoserial生成攻…

CC攻击和其防御策略

CC攻击简介 CC攻击&#xff0c;又称为Challenge Collapsar攻击&#xff0c;是一种常见的DDoS&#xff08;分布式拒绝服务&#xff09;攻击方式&#xff0c;旨在使Web服务在第七层协议层面遭受攻击。攻击者并不需要大量的肉鸡来实施CC攻击&#xff0c;相反&#xff0c;他们使用…

Flyway Desktop updated

Flyway Desktop updated 为比较工件序列化和反序列化添加了额外的调试日志记录。 Flyway Desktop现在将记住以前用于创建项目和匹配克隆的位置。 新的脱机许可工作流现在已在Microsoft Windows上启用。 现在&#xff0c;在配置目标数据库列表时&#xff0c;环境ID是可见的。 现…

HTML图像标签

html文件&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>图像标签学习</title> </head> <body> <img src"../resources/image/01.jpg" alt"小狗图…

【机器学习】集成模型/集成学习:多个模型相结合实现更好的预测

1. 概述 1.1 什么是集成模型/集成学习 "模型集成"和"集成学习"是相同的概念。它们都指的是将多个机器学习模型组合在一起&#xff0c;以提高预测的准确性和稳定性的技术。通过结合多个模型的预测结果&#xff0c;集成学习可以减少单个模型的偏差和方差&am…

2023年全球及中国分离纯化装备市场发展概况分析:未来市场将持续增长[图]

随着创新药物的研发加速&#xff0c;纯化环节在药物生产过程中的重要性也将日益凸显&#xff0c;纯化设备市场未来有望不断增长。2022年&#xff0c;全球小分子药物分离纯化装备市场规模达到45美元&#xff0c;期间复合年增长率为21.9%&#xff1b;预计未来全球小分子药物分离纯…

使用标准模板 MRI 主题根据 EEG 数据计算前向算子

# https://mne.tools/stable/auto_tutorials/forward/35_eeg_no_mri.html# 本教程说明如何使用标准模板 MRI 主题根据 EEG 数据计算前向算子 # # 成人模板 MRI (fsaverage) # 首先我们展示如何fsaverage用作替代subject# Authors: Alexandre Gramfort <alexandre.gramfortin…

vscode摸鱼插件开发

不知道大家在写代码的时候&#xff0c;摸不摸鱼&#xff0c;是不是时不时得打开一下微博&#xff0c;看看今天发生了什么大事&#xff0c;又有谁塌房&#xff0c;而你没有及时赶上。 为此&#xff0c;我决定开发一个vscode插件&#xff0c;来查看微博热搜 插件名称&#xff1…

每日一练 | 华为认证真题练习Day121

1、如下图所示的交换网络&#xff0c;所有交换机都运行了STP协议。当拓扑稳定后&#xff0c;在下列那台交换机上修改配置BPDU的发送周期&#xff0c;可以影响SWD配置BPDU的发送周期 A. SWD B. SWC C. SWB D. SWA 2、如下图所示的网络&#xff0c;交换机的MAC地址已标出。在S…

(数据结构)单链表的相关操作

//1.预编译部分#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>//2.单链表的结构体typedef struct LNode{int data;struct LNode* next; //因为next指针指向的为结构体类型&#xff0c;所以类型为struct LNode*}LNode, * LinkList; …

如何保障Facebook账号登录稳定?跨境人必看

作为全球最大的社交媒体平台&#xff0c;Facebook已成为众多跨境人们拓展海外市场的重要渠道。然而&#xff0c;Facebook对跨境业务卖家的监管越来越严格&#xff0c;封号政策也日趋严厉。对于想要在Facebook上开展业务的跨境人们而言&#xff0c;大家是否被Facebook封号问题困…

如何对需求变更进行精准的风险评估?

1、明确需求变更背景和目的 首先需要了解需求变更的背景&#xff0c;即需求产生的原因和环境&#xff0c;如需求变更是由业务变化、用户需求变化、技术限制、资源限制等因素引起的。其次需要明确需求变更目的是为了解决问题还是满足需求。 明确需求变更背景和目的&#xff0c;有…