记生产OOM的故障分析

一、引言

生产上告警,交易堵塞,服务无响应,使用jstack、jmap、jhat命令进行故障分析。

Java虚拟机(Java Virtual Machine,简称JVM)作为Java语言的核心组件,为Java程序提供了运行环境和内存管理机制。本文将系统地介绍JVM的基本架构、工作原理以及相关实战案例,旨在帮助读者对JVM有更全面且深入的理解。

二、JVM概述

JVM是Java平台的一部分,负责将Java字节码转换为机器指令并在不同的操作系统上执行。它屏蔽了底层硬件和操作系统的差异,使得“一次编写,到处运行”的理念得以实现。

三、JVM架构

四、垃圾回收

使用jstat 查看内存变化情况以及垃圾回收次数、时间,可以看到Eden的内存满了之后,就会做一次YGC,老年代的内存满了之后,会做FGC。

jstat -gcutil 1992 1000 1000

代码如下:

import java.util.HashMap;
import java.util.Map;/*** @Author: thinkpad* @Date: 2024-02-04 22:19*/
public class GCDemo {public static void main(String[] args) throws InterruptedException {Thread.sleep(10000);Map gc1Map = new HashMap();Map gc2Map = new HashMap();for(int i = 0; i < 10000; i++){// 每个byte占1字节,所以为了得到1M需要大约1024 * 1024个字节int oneMegabyte = 1024 * 1024;// 创建一个1MB的byte数组byte[] largeObject = new byte[oneMegabyte];gc1Map.put(i, largeObject);gc2Map.put(i, largeObject);System.out.println("i = " + i);Thread.sleep(200);}}
}

五、实战案例

本次生产上的故障是由于使用POI进行Excel操作所引起的,现在,我们来分析POI导致的原因。

生产上的故障,使用XSSFWorkbook操作十几万条记录,代码大致如下:

import org.apache.commons.compress.utils.Lists;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.io.File;
import java.util.List;/*** @Author: thinkpad* @Date: 2024-02-24 21:53*/
public class XssfWorkbookDemo {public static void main(String[] args) {try {File testcaseFile = new File("E:/testcase.xlsx");XSSFWorkbook xssfWorkbook = new XSSFWorkbook(testcaseFile);XSSFSheet sheet = xssfWorkbook.getSheetAt(0);List<TestCase> testCaseList = Lists.newArrayList();int lastRowNum = sheet.getLastRowNum();System.out.println("lastRowNum: " + lastRowNum);for(int rowIndex = 1; rowIndex <= lastRowNum; rowIndex++){XSSFRow row = sheet.getRow(rowIndex);String[] cellArray = new String[row.getLastCellNum() - row.getFirstCellNum()];for(int cellNum = row.getFirstCellNum(); cellNum < row.getLastCellNum(); cellNum++){cellArray[cellNum] = row.getCell(cellNum).toString();}TestCase testCase = new TestCase();testCase.setCaseId(cellArray[0]);testCase.setUrl(cellArray[1]);testCase.setLevel(cellArray[2]);testCase.setDescribe(cellArray[3]);testCaseList.add(testCase);}testCaseList.stream().forEach(testcase->{System.out.println(testcase.toString());});}catch (Exception e){e.printStackTrace();}}
}

导致内存溢出,通过jmap和jhat分析,使用jmap导出内存,命令如下

jmap -dump:live,format=b,file=heap-dump-pid.bin pid

通过jhat分析,关注 show heap histogram(内存实例的分布)

通过show heap histogram分析,发现内存占用多的如下分布, org.apache.xmlbeans.impl.store.Xobj占用了大量的内存,这是因为使用POI读取excel时,会产生大量的xml解析,因此如果有很多记录时,就会导致内存溢出。

 由于使用XSSFWorkbook读取大量excel记录时,会内存溢出,因此尝试SXSSFWorkbook读取excel,代码大致如下

package com.fd.demo;import org.apache.commons.compress.utils.Lists;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.io.File;
import java.io.FileInputStream;
import java.util.List;/*** @Author: thinkpad* @Date: 2024-02-24 21:53*/
public class SXssfWorkbookDemo {public static void main(String[] args) {try {File testcaseFile = new File("E:/testcase.xlsx");FileInputStream fis = new FileInputStream(testcaseFile);XSSFWorkbook xssfWorkbook = new XSSFWorkbook(fis);SXSSFWorkbook workbook = new SXSSFWorkbook(xssfWorkbook, 1000);Sheet sheet = workbook.getXSSFWorkbook().getSheetAt(0);List<TestCase> testCaseList = Lists.newArrayList();int lastRowNum = sheet.getLastRowNum();System.out.println("lastRowNum: " + lastRowNum);for(int rowIndex = 1; rowIndex <= lastRowNum; rowIndex++){Row row = sheet.getRow(rowIndex);String[] cellArray = new String[row.getLastCellNum() - row.getFirstCellNum()];for(int cellNum = row.getFirstCellNum(); cellNum < row.getLastCellNum(); cellNum++){cellArray[cellNum] = row.getCell(cellNum).toString();}TestCase testCase = new TestCase();testCase.setCaseId(cellArray[0]);testCase.setUrl(cellArray[1]);testCase.setLevel(cellArray[2]);testCase.setDescribe(cellArray[3]);testCase.setDescribe1(cellArray[4]);testCase.setDescribe2(cellArray[5]);testCase.setDescribe3(cellArray[6]);testCase.setDescribe4(cellArray[7]);testCase.setDescribe5(cellArray[8]);testCase.setDescribe6(cellArray[9]);testCase.setDescribe7(cellArray[10]);testCase.setDescribe8(cellArray[11]);testCase.setDescribe9(cellArray[12]);testCase.setDescribe10(cellArray[13]);testCase.setDescribe11(cellArray[14]);testCase.setDescribe12(cellArray[15]);testCase.setDescribe13(cellArray[16]);testCase.setDescribe14(cellArray[17]);testCase.setDescribe15(cellArray[18]);testCase.setDescribe16(cellArray[19]);testCase.setDescribe17(cellArray[20]);testCase.setDescribe18(cellArray[21]);testCaseList.add(testCase);}for(int i = 0; i < testCaseList.size(); i++){System.out.println(testCaseList.get(i).toString());}Thread.sleep(1000000);}catch (Exception e){e.printStackTrace();}}
}

 导致内存溢出,通过jmap和jhat分析,使用jmap导出内存,命令如下

jmap -dump:live,format=b,file=heap-dump-pid.bin pid

通过jhat分析,关注 show heap histogram(内存实例的分布)

六、总结

内存溢出的分析需要用到jmap,jhat命令

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

01背包问题:组合问题

01背包问题&#xff1a;组合问题 题目 思路 将nums数组分成left和right两组&#xff0c;分别表示相加和相减的两部分&#xff0c;则&#xff1a; left - right targetleft right sum 进而得到left为确定数如下&#xff0c;且left必须为整数&#xff0c;小数表示组合不存在&…

供应链大数据:穿越经济迷雾的指南针

随着经济形势的变幻莫测&#xff0c;企业运营面临着前所未有的挑战。在这个充满不确定性的时代&#xff0c;供应链大数据如同一盏明亮的指南针&#xff0c;为企业提供精准的方向指引。下面&#xff0c;我们将深入探讨供应链大数据如何帮助企业洞察市场趋势、优化库存管理、降低…

绝对路径拼接漏洞 [NISACTF 2022]babyupload

打开题目 最开始以为是文件上传的漏洞 结果发现无论我们上传什么文件都会显示bad filename 去网上看了大佬的wp知道 我们直接去看源代码得到提示 /source 那我们去访问一下这个路径看看 得到一个下载文件 用记事本打开得到 源代码如下 from flask import Flask, request, r…

支付流程的理解

开发指引-JSAPI支付 | 微信支付商户平台文档中心 业务流程图&#xff1a; 首先&#xff0c;从业务流程&#xff0c;当有人问你的时候&#xff0c;反问&#xff1a;公司有没有确认跟支付宝合作还是跟微信合作&#xff0c;看有没有签订协议&#xff0c;有的话&#xff0c;要确认…

数学建模【遗传算法】

一、遗传算法简介 从做菜说起&#xff0c;小魏是一名大厨&#xff0c;想要创造一道美味的菜肴。首先随机生成多个原始配方&#xff0c;每种配方所用的原料&#xff08;鸭脖、鸡肉、大肠等&#xff09;与手法&#xff08;煎炒焖炸卤炖&#xff09;组合不同&#xff0c;现实中考…

pytest教程-12-fixture作用域

领取资料&#xff0c;咨询答疑&#xff0c;请➕wei: June__Go 上一小节我们学习了pytest fixture的基本使用方法&#xff0c;本小节我们讲解一下fixture的作用域。 fixture前后置区分 控制fixture的前置和后置操作是通过yield关键字进行来区分的&#xff0c;代码在yield前面…

编曲学习:高叠和弦 挂留和弦 和弦实战应用

高叠和弦 挂留和弦 和弦实战应用小鹅通-专注内容付费的技术服务商https://app8epdhy0u9502.pc.xiaoe-tech.com/live_pc/l_65d4826fe4b04c10a1310517?course_id=course_2XLKtQnQx9GrQHac7OPmHD9tqbv 七和弦 以三和弦举例,三和弦上面叠一个三度的音,就变成了七和弦。 从下到…

halcon中的2D测量-椭圆

一、定义 二维测量指的是测量二维几何图形的参数&#xff0c;例如圆、椭圆、圆弧、矩形的相关参数。这里的参数对圆来说可以是半径&#xff1b;椭圆可以是长半轴、短半轴&#xff1b;矩形则包括宽和高。 二、基本步骤 1.创建测量模型 使用算子 create_metrology_model 2.设…

leetcode hot100 买卖股票的最佳时机二

注意&#xff0c;本题是针对股票可以进行多次交易&#xff0c;但是下次买入的时候必须保证上次买入的已经卖出才可以。 动态规划可以解决整个股票买卖系列问题。 dp数组含义&#xff1a; dp[i][0]表示第i天不持有股票的最大现金 dp[i][1]表示第i天持有股票的最大现金 递归公…

SOLIDWORKS 查找并修复装配体配合错误

我们在SOLIDWORKS 正版软件进行装配体装配时&#xff0c;时常会出现一些报错&#xff0c;例如在配合、装配体特征或被装配体参考引用的零部件和子装配体中。一些常见的错误&#xff0c;如一个零部件的过定义会引发更多其他错误信息&#xff0c;并导致装配体停止解析配合关系。下…

背包问题(介绍+例题+代码+注解)

目录 介绍&#xff1a; 一、01背包 题目描述 输入描述: 输出描述: 代码&#xff1a; 二、完全背包 题目描述 输入描述: 输出描述: 代码&#xff1a; 三、多重背包 题目描述 输入描述: 输出描述: 代码&#xff1a; 四、背包问题 题目描述 输入描述: 输出描…

27.HarmonyOS App(JAVA)可复用列表项的ListContainer

可复用列表项的ListContainer 简短的列表可以通过定向布局实现,但是如果列表项非常多,则使用定向布局就不再合适。如需要创建50个列表项的列表,那么用定向布局实现至少需要创建50个以上的组件了。然而,限于设备屏幕大小的限制,绝大多数组件不会显示在屏幕上,却会占据大量的内存…