JVM实战(30)——模拟堆内存溢出

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析

阶段4、深入jdk其余源码解析

阶段5、深入jvm源码解析

一、简介

本章,我们将通过示例代码演示Java堆内存区域是如何发生内存溢出的,并根据内存快照进行分析。

我们回顾下堆内存溢出的一个场景:系统负载很高,不停的在Eden区创建新对象,直到触发Young GC,但是由于并发太高,Young GC发现Eden区存活对象非常多,Survivor无法容纳,只能把大批存活对象转移到老年代。经过几次这种Young GC之后,老年代也满了,于是触发Full GC,但是Full GC之后老年代里还是塞满了对象,导致Young GC过后的存活对象无处可安放,最终引发堆内存溢出。

二、示例程序

2.1 程序源码

    package com.mx.jvm;import java.util.ArrayList;import java.util.List;public class Demo3 {public static void main(String[] args) {long counter = 0L;List<Object> list = new ArrayList<Object>();while (true) {list.add(new Object());System.out.println("当前创建了第" + ++counter + "个对象");}}

上述代码很简单,就是不停的创建对象,由于对象由一个while循环外部的List引用着,且main()方法是无限执行的,所以这些创建的对象始终不会被回收掉。这样最终Eden区、老年代的空间都会被占满。

2.2 JVM参数

我们设置下堆内存的总大小为5MB:-Xms5m -Xmx5m -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -Xloggc:gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./,这样就可以快速触发堆内存溢出。程序执行后的打印日志输出如下:

    当前创建了第160063个对象当前创建了第160064个对象当前创建了第160065个对象java.lang.OutOfMemoryError: Java heap spaceDumping heap to ./\java_pid6412.hprof ...Heap dump file created [7250823 bytes in 0.058 secs]Exception in thread "main" java.lang.OutOfMemoryError: Java heap spaceat java.util.Arrays.copyOf(Arrays.java:3210)at java.util.Arrays.copyOf(Arrays.java:3181)at java.util.ArrayList.grow(ArrayList.java:261)at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:235)at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:227)at java.util.ArrayList.add(ArrayList.java:458)at com.mx.jvm.Demo3.main(Demo3.java:12)

可以看到,在5MB的堆内存中,不断创建Obejct对象,当创建到第160065个对象时,堆内存实在放不下了,从而引发java.lang.OutOfMemoryError

三、问题分析

我们通过程序日志中的报错“java.lang.OutOfMemoryError: Java heap space”,知道发生了Java堆内存溢出。针对Java堆内存溢出,一般不用看GC日志,因为堆内存溢出伴随的GC日志内容会非常多,我们直接分析dump出的内存快照即可。

采用MAT打开内存快照java_pid6412.hprof(进程名不同,文件名也略有区别):

可以看到一大堆对象占据了81.19%的堆内存,我们直接点击"See stacktrace",看看这些对象是在程序哪里创建出来的:

很显然,main方法的第12行,一直调用list.add(new Object()),由此直接引发了内存溢出,我们只要有针对性的修复我们代码的bug即可。

四、总结

本章,我们通过代码示例模拟了堆内存溢出的场景,Java堆内存也是最容易出现内存溢出的区域。基本的分析思路就是dump出事发现场的内存快照,然后通过MAT进行查看,分析出内存占用最多的对象,然后分析线程调用栈,找到代码位置,最后进行优化即可。

从下一章开始,我们将给出真实的生产环境案例,看看这些案例是如何引起OOM以及排查和解决的思路方法。

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

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

相关文章

ME51N屏幕增强——添加历史订单价格字段

参考&#xff1a; 资料&#xff1a;SAP所有模块用户出口(User Exits) _coopa003-CSDN博客 SAP ABAP常用增强记录文档_sap自动过账增强-CSDN博客 https://www.cnblogs.com/zyhcs/p/15759434.html 需求&#xff1a; 增加给OA传输接口的字段。 采购申请增加历史价格显示。 已经…

Android 水印效果

Android 水印效果 本文主要介绍下android 中水印的实现效果. 实现的方式有多种,就不一一赘述了, 本文就是通过自定义drawable来实现水印. 不多说,直接上代码吧: import android.content.Context; import android.content.res.Resources; import android.graphics.Canvas; i…

【QT+QGIS跨平台编译】之七:【libjpeg+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、libjpeg介绍二、文件下载三、文件分析四、pro文件五、编译实践一、libjpeg介绍 libjpeg是一个广泛使用的jpeg图像压缩和解压的函数库,采用 C 语言开发。 2013年1月,Independent JPEG Group发布了版本9,对新引入的无损编码模式进行了改进。2022年1月,发布了版…

蓝桥杯省赛无忧 排序 课件40 冒泡排序

01 冒泡排序的思想 02 冒泡排序的实现 03 例题讲解 #include <iostream> using namespace std; void bubbleSort(int arr[], int n) {for (int i 0; i < n-1; i) { for (int j 0; j < n-i-1; j) {if (arr[j] > arr[j1]) {int temp arr[j];arr[j] arr[j1…

Django开发_18_REST Framework

一、介绍 二、使用 &#xff08;一&#xff09;安装依赖 pip install djangorestframework pip install httpie &#xff08;二&#xff09;序列化 1.models.py创建模型类 2.admin.py中注册模型类 3.创建serializer.py文件 创建序列化类 4.views.py中编写视图函数 首先要…

Java进阶之旅第八天

Java进阶之旅第八天 文章目录 Java进阶之旅第八天异常作用分类编译时异常运行时异常 异常的处理方式默认的处理方式自己处理(捕获异常) 异常的常见方法Throwable 的成员方法代码结果 异常的抛出处理throws和throw 自定义异常 异常 作用 自己写的代码在运行过程中发生某种错误…

wayland(xdg_wm_base) + egl + opengles 纹理贴图实例

文章目录 前言一、纹理贴图1. 纹理贴图介绍2. 使用opengles 实现纹理贴图的主要步骤二、代码实例1. egl_wayland_texture.c2. xdg-shell-client-protocol.h 和 xdg-shell-protocol.c3. 编译4. 运行总结前言 本文主要介绍如何在一个wayland client 里面使用 egl + opengles 实现…

[极客大挑战 2019]BabySQL1

发现union select被过滤了&#xff0c;双写绕过 or、from被过滤 where被过滤 在b4bysql中找到flag

架构师之路(十四)计算机网络(网络层)

前置知识&#xff08;了解&#xff09;&#xff1a;计算机基础。 作为架构师&#xff0c;我们所设计的系统很少为单机系统&#xff0c;因此有必要了解计算机和计算机之间是怎么联系的。局域网的集群和混合云的网络有啥区别。系统交互的时候网络会存在什么瓶颈。 网络层提供主机…

探索Gin框架:快速构建高性能的Golang Web应用

前言 Gin框架是一个轻量级的Web框架&#xff0c;基于Go语言开发&#xff0c;旨在提供高性能和简洁的API。它具有快速的路由和中间件支持&#xff0c;使得构建Web应用变得更加简单和高效。无论是构建小型的API服务还是大型的Web应用&#xff0c;Gin框架都能够满足你的需求。 无论…

go api(get post传参,数据库,redis) 测试

介绍&#xff1a;分别测试get请求&#xff0c;post请求&#xff0c;请求链接数据库&#xff0c;以及redis操作。 1.api代码 package mainimport (_ "database/sql""encoding/json""github.com/gin-gonic/gin""go-test/com.zs/database&quo…

[BSidesCF 2020]Had a bad day

先看url&#xff0c;发现可能有注入 http://655c742e-b427-485c-9e15-20a1e7ef1717.node5.buuoj.cn:81/index.php?categorywoofers 试试能不能查看index.php直接?categoryindex.php不行&#xff0c;试试伪协议 把.php去掉试试 base64解码 <?php$file $_GET[category];…

Vue3+TS+dhtmlx-gantt实现甘特图

实现样式 因为只做展示&#xff0c;所以实现很简单 实现功能 自定义列头增加斑马线&#xff0c;实际结束时间&#xff08;自定义实现&#xff09;自定义进度展示&#xff0c;根据层级让进度背景颜色变浅marker标记今天自定义提示框内容 实现 import { gantt } from "d…

STM32F407移植OpenHarmony笔记1

参考文档&#xff1a; OpenAtom OpenHarmonywidthdevice-width,initial-scale1.0https://docs.openharmony.cn/pages/v3.2/zh-cn/device-dev/get-code/gettools-acquire.md/ 搭建环境 安装linux系统: Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-91-generic x86_64) 下载源代码&a…

如何在转接的NVME 固态盘上安装WIN 系统并引导启动

问题&#xff1a; 家里的台式机一直挂着一块128G的SSD固态盘&#xff0c;由于家里自己建了NAS存储&#xff0c;所以基本数据都在NAS里&#xff0c;台式机就没有挂机械盘了&#xff0c;但是最近台式机空间被系统侵蚀&#xff0c;显然就不够用了&#xff0c;除了清理系统&#xf…

bash 5.2中文修订4

Compound Commands 复合命令 复合命令是 shell 编程语言的结构。每个构造都以保留字或控制运算符开始&#xff0c;并以相应的保留字或运算符终止。与复合命令关联的任何重定向&#xff08;请参阅 Redirections &#xff09;都适用于该复合命令中的所有命令&#xff0c;除非显式…

harmonyOS app 开发环境配置流程

1.安装DevEco Studio&#xff0c;注意nodejs版本&#xff0c;安装过程中有提示&#xff0c;添加hdc到系统环境变量中&#xff0c;用于调用hdc命令 2.开启真机设备的开发人员选项&#xff0c;以及开启5555端口&#xff08;需要连接usb线&#xff09; https://developer.harmonyo…

vue3使用AntV G6 (图可视化引擎)历程[二]

上期回顾&#xff1a;历程[一]描述了基本的树状图的绘制&#xff0c;默认节点类型defaultNode中的type是circle,下面这篇描述的是节点抽离自定义节点并做数据静态渲染。 官网地址&#xff1a;https://g6-next.antv.antgroup.com/manual/introduction 一、案例效果 二、自定义节…

正则表达式元字符-详细说明

字符 说明 \ 将下一字符标记为特殊字符、文本、反向引用或八进制转义符。例如&#xff0c;"n"匹配字符"n"。"\n"匹配换行符。序列"\\\\"匹配"\\"&#xff0c;"\\("匹配"("。 ^ 匹配输入字符串…

编写Bash脚本程序从记录文件中提取history命令的优化,再介绍linux bash语法和结构

目 录 一、引言 二、脚本代码实现 三、bash语法和结构 &#xff08;一&#xff09;基本语法 1、脚本开始与结束 2、注释 3、变量 4、数据类型 5、控制结构 6、循环控制 7、函数 8、算术运算 9、算术操作符和逻辑操作符 &#xff08;二&#xff09;命令相关…