当前位置: 首页 > news >正文

《JVM第10课》内存溢出(OOM)排查过程

文章目录

    • 常用命令
      • 1. jps
      • 2. jconsole
      • 3. jstat
      • 4. jmap
    • 工具
      • 1.jvisualvm

排查OOM的方法其实很简单很简单。

  1. 如果能找到拋OOM的日志,可以在日志里看到是哪一行抛出的OOM异常。
  2. 如果找不到日志,那么处理方式是导出Java进程的内存快照,然后用工具查看OOM日志。
  3. 如果打印OOM日志的行不是导致OOM的罪魁祸首(因为也许是别的地方把内存占完了,刚好此处要申请内存,就抛OOM了),那就通过工具查看哪些对象占用了大量内存未释放,进而找到这些对象的所在的类。

在学习如何排查OOM之前,先来学习几个常用的命令,它们对于分析内存、线程、垃圾收集有着很好的帮助。如果不想浪费时间也可直接跳到“工具”目录。

常用命令

1. jps

jps 是 JDK 自带的命令行工具,用于查看 Java 进程。

我们都知道 Linux 中 ps 命令是用来查看进程的,jps 相当于是 java ps,是只查看 Java 进程的命令,在Windows和Linux上都可以。

例如我们写一个main方法:

public class Test1 {public static void main(String[] args) throws InterruptedException {while (true) {Thread.sleep(1000L);System.out.println("hello world");}}
}

使用jps命令查看进程号:

在这里插入图片描述

2. jconsole

jconsole 是 JDK 自带的一个图形化监控工具。

只能在Windows上使用,在Linux上一般打不开除非有图形界面库。

用它可以连接到正在运行的 Java 应用程序,并监视其 CPU 使用率、内存使用情况、线程状态、有无死锁、类加载等。jconsole 对于实时监控 Java 应用程序的健康状况和进行性能调优非常有用。

我们直接在控制台输入 jconsole 回车便可打开监控工具。

step1: 输入控制台输入jconsole,回车,打开如下界面。

在这里插入图片描述

step2: 选择本地进程,如我这里选的是刚刚启动的Test1,然后选择“不安全的连接”。

在这里插入图片描述

然后就能非常直观的监控 CPU、内存、线程、类的状态啦~,如图:

在这里插入图片描述

在“线程”tab页,还可以非常方便的检测当前进程有无死锁状态的线程,这也是 jconsole 最常用的功能之一。如下图:

在这里插入图片描述

也可以使用jconsole连接远程的Java进程,但是一般不这么用,不做过多讲解。

3. jstat

jstat 相当于是 jconsole 的命令版,jconsole 是 jstat 的可视化版。

jstat 也是 JDK 自带的命令行工具,用于监控 Java 程序的垃圾收集、类加载、JIT编译等方面的信息。

常用命令:

jstat -class 查看类加载和卸载情况

jstat -compiler 查看JIT编译器的编译情况

使用方式见下图:

在这里插入图片描述

上面两个命令我们一般也用不到,最常用的命令还是 jstat -gcutil

jstat -gcutil 命令用于查看垃圾收集情况,包括新生代和老年代的垃圾收集信息。

在这里插入图片描述

解释图中命令:jstat -gc 是查看垃圾收集情况,1204是进程号,1000是每1秒打印一次,5是一共打印5次。这里的值是百分比,S1区被占用了26.78%,Eden区被占用了47.65%。

如果不想查看百分百而查看具体的值,可使用 jstat -gc 命令:

在这里插入图片描述

4. jmap

jmap 是 JDK 自带的一个命令行工具,主要用于打印出 Java 进程的内存快照,包括堆内存的详细信息、垃圾回收器信息等。它对于分析和诊断内存泄漏或需要优化内存使用的情况下非常有用。

使用方式:

jmap -dump:file=<文件名> <进程ID>

使用示例:

我们改造一下测试用例,让线程创建很多不能被回收的静态 Integer 对象并且让线程保持运行状态。如下

public class Test1 {static List<Integer> list = new ArrayList<>();public static void main(String[] args) {for (int i = 0; i < 1000000; i++) {list.add(i+1);}while (true) {}}
}

导出内存快照,如下:

在这里插入图片描述

然后就会生成一个 d.hprof 文件,接下来就可以用可视化工具检测内存状态啦~

其实,为了在发生OOM时及时导出快照信息,我们可以在 Java 应用启动时加上参数,让它在发生OOM时自动dump内存快照。参数如下

  • -XX:+HeapDumpOnOutOfMemoryError: 当 JVM 抛出 OOM 时,自动导出内存快照。
  • -XX:HeapDumpPath=<路径>: 指定快照文件的保存路径。如果没有指定这个参数,默认情况下,堆转储文件会被写入到工作目录下,文件名为 java_pid<进程id>.hprof。

工具

工具有很多,比如 jvisualvm、JProfile、Eclipse Memory Analyzer等等,各有千秋。我们这里只演示jvisualvm的用法。

我们先创建一段代码,让它抛出OOM异常并自动导出内存快照:

package com.fanren;import java.util.ArrayList;
import java.util.List;public class Test1 {static List<Integer> list = new ArrayList<>();public static void main(String[] args) {for (int i = 0; i < 1000000; i++) {list.add(i+1);}}
}

然后配置启动类,配置堆内存为10m并且发生OOM时自动导出内存快照:

在这里插入图片描述

接着运行就会报错:

在这里插入图片描述

已经发生OOM异常并且导出了 java_pid25104.hprof 文件。

接下来我们就可以在工具中使用 java_pid25104.hprof 文件排查OOM的原因了。

1.jvisualvm

jvisualvm在JDK 6 Update 7版本后作为标准工具被引入,也就是说 jvisualvm 是 JDK 自带的,省的下载了。

我们在控制台输入 jvisualvm 即可打开该工具。

在这里插入图片描述

如上图,进来后如果本地有正在运行的 Java 进程,可以监控此进程,双击打开可以看到右侧也有类似于 jconsole 的监控界面。也可以在此界面执行垃圾回收或是导出(dump)当前堆的快照,非常方便。

jvisualvm 不仅可以监控正在运行的进程内存状况,也可以导入内存快照。只需点击左上角的“装入快照”,我们把刚刚导出的 java_pid25104.hprof 给装入进来后如下图:

在这里插入图片描述

“概要”视图里已经提示了发生OOM的线程,点击之后就可以看到报错的行号:

在这里插入图片描述

可以发现正是我们的问题代码所在的行。

如果通过报错行号找到的不是导致OOM的罪魁祸首,那么可以点击“类”视图:

在这里插入图片描述

“类”视图里按照内存大小倒序后可以看到,Integer 类型对象占用了最多的空间,我们双击此行进入到“实例数”视图。如下:

在这里插入图片描述

在这个视图里选中一个对象实例,就可以在右侧“引用”模块查看到引用该对象的类是 Test1。

这样的话就可以得出结论:内存溢出是 Test1 类里面的 Integer 对象过多导致的。

于是我们就可以排查代码写得是不是有问题了。

相关文章:

《JVM第10课》内存溢出(OOM)排查过程

文章目录 常用命令1. jps2. jconsole3. jstat4. jmap 工具1.jvisualvm 排查OOM的方法其实很简单很简单。 如果能找到拋OOM的日志&#xff0c;可以在日志里看到是哪一行抛出的OOM异常。如果找不到日志&#xff0c;那么处理方式是导出Java进程的内存快照&#xff0c;然后用工具查…...

Thinkphp6视图介绍

一.MVC MVC 软件系统分为三个基本部分&#xff1a;模型&#xff08;Model&#xff09;、视图&#xff08;View&#xff09;和控制器&#xff08;Controller&#xff09; ThinkPHP6 是一个典型的 MVC 架构 控制器—控制器&#xff0c;用于将用户请求转发给相应的Model进行处理&a…...

躺平成长-人工智能进行编程-(12)

躺平成长&#xff1a; 让每一个人在科技&#xff08;开源的网络/智能科技对于生活琐事的处理&#xff09;的帮助下&#xff0c;实现养生反卷&#xff0c;躺平成长。 开源竞争&#xff1a; 当你无法彻底掌握技术的时候&#xff0c;你就开源这个技术&#xff0c;形成技术依赖&a…...

计算机网络中的域名系统(DNS)及其优化技术

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 计算机网络中的域名系统&#xff08;DNS&#xff09;及其优化技术 计算机网络中的域名系统&#xff08;DNS&#xff09;及其优化…...

Matplotlib库中show()函数的用法

在Matplotlib库中使用show()函数是用于显示绘制的图形的函数。它将图形显示在屏幕上或保存到文件中。show()函数通常在绘制完图形后调用。 Matplotlib是一个用于绘制2D图形的Python库&#xff0c;它提供了丰富的绘图工具和函数&#xff0c;可以用于创建各种类型的图表&#xf…...

C#中object和dynamic

在C#中&#xff0c;object和dynamic都是用于存储不同类型值的类型&#xff0c;但它们之间存在一些关键的区别&#xff1a; object object是C#中的基元类型之一&#xff0c;是所有其他类型的最终基类。当你将一个值赋给object类型的变量时&#xff0c;编译器会执行装箱操作&am…...

Spring Cloud Eureka 服务注册与发现

Spring Cloud Eureka 服务注册与发现 一、Eureka基础知识概述1.Eureka两个核心组件2.Eureka 服务注册与发现 二、Eureka单机搭建三、Eureka集群搭建四、心跳续约五、Eureka自我保护机制 一、Eureka基础知识概述 1.Eureka两个核心组件 Eureka Server &#xff1a;服务注册中心…...

【WPF】Prism学习(三)

Prism Commands 1.复合命令&#xff08;Composite Commanding&#xff09; 这段内容主要介绍了在应用程序中如何使用复合命令&#xff08;Composite Commands&#xff09;来实现多个视图模型&#xff08;ViewModels&#xff09;上的命令。以下是对这段内容的解释&#xff1a; …...

1+X应急响应(网络)系统加固:

系统加固&#xff1a; 数据库的重要性&#xff1a; 数据库面临的风险&#xff1a; 数据库加固&#xff1a; 业务系统加固&#xff1a; 安全设备加固&#xff1a; 网络设备加固&#xff1a;...

使用 Grafana api 查询 Datasource 数据

一、使用grafana 的api 接口 官方API 二、生成Api key 点击 Administration -》Users and accss -》Service accounts 进入页面 点击Add service account 创建 service account 点击Add service account token 点击 Generate token , 就可以生成 api key 了 三、进入grafana…...

【电子设计】按键LED控制与FreeRTOS

1. 安装Keilv5 打开野火资料,寻找软件包 解压后得到的信息 百度网盘 请输入提取码 提取码:gfpp 安装526或者533版本都可以 下载需要的 F1、F4、F7、H7 名字的 DFP pack 芯片包 安装完 keil 后直接双击安装 注册操作,解压注册文件夹后根据里面的图示步骤操作 打开说明 STM…...

JMeter中添加请求头

在JMeter中添加请求头的步骤如下&#xff1a; 1.打开HTTP信息头管理器 &#xff1a; 首先&#xff0c;你需要进入JMeter的HTTP请求组件。这可以通过在HTTP请求测试元素上右键点击&#xff0c;然后选择“添加 > 配置元件 > HTTP信息头管理器”来完成。 2.添加新的请求头…...

VMD + CEEMDAN 二次分解,CNN-LSTM预测模型

往期精彩内容&#xff1a; 时序预测&#xff1a;LSTM、ARIMA、Holt-Winters、SARIMA模型的分析与比较 全是干货 | 数据集、学习资料、建模资源分享&#xff01; EMD变体分解效果最好算法——CEEMDAN&#xff08;五&#xff09;-CSDN博客 拒绝信息泄露&#xff01;VMD滚动分…...

【Linux系统编程】第四十六弹---线程同步与生产消费模型深度解析

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、Linux线程同步 1.1、同步概念与竞态条件 1.2、条件变量 1.2.1、认识条件变量接口 1.2.2、举例子认识条件变量 1.2.3、…...

VoIP是什么?

IP 语音 (VoIP)&#xff08;Voice over Internet Protocol&#xff09; 是一种通过互联网拨打电话的方法。与旧的固定电话系统不同&#xff0c;互联网并非设计用于在连接的人之间实时传输音频信号。必须构建专门的技术和协议才能使之成为可能&#xff0c;这些技术和协议构成了 …...

MySQL 中的集群部署方案

文章目录 MySQL 中的集群部署方案MySQL ReplicationMySQL Group ReplicationInnoDB ClusterInnoDB ClusterSetInnoDB ReplicaSetMMMMHAGalera ClusterMySQL ClusterMySQL Fabric 总结参考 MySQL 中的集群部署方案 MySQL Replication MySQL Replication 是官方提供的主从同步方…...

《设计模式》创建型模式总结

目录 创建型模式概述 Factory Method: 唯一的类创建型模式 Abstract Factory Builder模式 Prototype模式 Singleton模式 最近在参与一个量化交易系统的项目&#xff0c;里面涉及到用java来重构部分vnpy的开源框架&#xff0c;因为是框架的搭建&#xff0c;所以会涉及到像…...

Conda安装与使用中的若干问题记录

Conda安装与使用中的若干问题记录 1.Anaconda 安装失败1.1.问题复述1.2.问题解决&#xff08;安装建议&#xff09; 2.虚拟环境pip install未安装至本虚拟环境2.1.问题复述2.2.问题解决 3.待补充 最近由于工作上的原因&#xff0c;要使用到Conda进行虚拟环境的管理&#xff0c;…...

人力资源招聘系统的革新之路:从传统到智能的转变

在全球化与数字化交织的今天&#xff0c;企业间的竞争日益激烈&#xff0c;而人才作为企业发展的核心驱动力&#xff0c;其重要性不言而喻。传统的人力资源招聘方式&#xff0c;如依赖纸质简历、人工筛选、面对面面试等&#xff0c;不仅效率低下&#xff0c;且难以精准匹配企业…...

Python网络爬虫与数据采集实战——网络协议与HTTP

目录 1. HTTP协议简介 2. 常见的请求方法 3. 状态码含义 实际应用中的HTTP协议 1. 如何在爬虫中使用HTTP协议 2. 模拟浏览器请求与爬虫反爬虫技术 3. 高级HTTP请求 实现爬虫时HTTP协议的优化与常见问题 总结 1. HTTP协议简介 HTTP的定义与作用 HTTP&#xff08;超文本…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...