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

Java进阶之Dump文件初体验

视频地址:https://www.bilibili.com/video/BV1Ak4y137oh

学习文章:https://d9bp4nr5ye.feishu.cn/wiki/VQoAwlzrXiLFZekuLIyc1uK5nqc


最近线上频繁的内存告警,同事A通过分析dump文件解决了这个问题,我当然是不会放过这种学习的机会。


文章目录

    • 一、分析dump文件
      • 1、下载dump文件
      • 2、查看dump文件
      • 3、分析dump文件
    • 二、扩展:JVM内存结构,回收规则
    • 三、实战

一、分析dump文件


1、下载dump文件

步骤命令描述
找到Java服务jps找到需要观察的Java服务进程。 也可以使用 ps -ef grep java

1. jps 属于JDK提供的命令
2. ps 是Linux提供的命令
生成dump文件jmapjmap -dump:file=/tmp/xdx_dump.bin 1

上面命令的含义就是在 /tmp 目录下生成一个名为 xdx_dump 的文件,格式为 bin,java服务的进程 1
压缩dump文件tar在真实线上生成的 dump 文件都很大,所以我们需要把它压缩成 tar.gz 文件,可以减少6倍以上的大小。

tar -zcvf xdx_dump_one.tar.gz xdx_dump_one.bin

上面命令的含义就是 把当前目录下的xdx_dump_one.bin文件,压缩成 xdx_dump_one.tar.gz 文件

2、查看dump文件


可以通过两种方式获取查看dump文件的软件

  1. 官网下载,可以拿到最新版本。 https://visualvm.github.io/
  2. 在JDK的 home/bin 目录下已经带了这个工具,并且还是中文的。

从服务器上下载压缩后的dump文件,拿到本地后再解压出来,双击打开 visualvm,把解压好的bin文件拖进去。然后你就可以看到堆中的数据信息了。

在这里插入图片描述


3、分析dump文件


在这里插入图片描述


毫无疑问,内存飙升,我们只需要看看当前系统中内存占比最大的是个什么东西,然后想办法干掉它。

在这里插入图片描述


二、扩展:JVM内存结构,回收规则


为了方便理解后面实战的部分,需要准备一点前置知识:JVM内存结构和回收机制。

Hotspot VM将内存划分为不同的三个物理区:新生代、老年代、永久代。其中新生代又被分成Edun区和两个Survivor区。

在这里插入图片描述

描述
新生代大多数对象在这里被创建,其中很多对象的生命周期很短。每次新生代的垃圾回收(又称Minor GC)后只有少量对象存活,所以选用复制算法,只需要少量的复制成本就可以完成回收。

新生代内又分三个区:一个Eden区,两个Survivor区(一般而言),大部分对象在Eden区中生成。当Eden区满时,还存活的对象将被复制到两个Survivor区(中的一个)。当这个Survivor区满时,此区的存活且不满足“晋升”条件的对象将被复制到另外一个Survivor区。对象每经历一次Minor GC,年龄加1,达到“晋升年龄阈值”后,被放到老年代,这个过程也称为“晋升”。显然,“晋升年龄阈值”的大小直接影响着对象在新生代中的停留时间。
老年代在新生代中经历了N次垃圾回收后仍然存活的对象,就会被放到年老代,该区域中对象存活率高。老年代的垃圾回收(又称Major GC)通常使用“标记-清理”或“标记-整理”算法。整堆包括新生代和老年代的垃圾回收称为Full GC(HotSpot VM里,除了CMS之外,其它能收集老年代的GC都会同时收集整个GC堆,包括新生代)。
永久代要存放元数据,例如Class、Method的元信息,与垃圾回收要回收的Java对象关系不大。相对于新生代和年老代来说,该区域的划分对垃圾回收影响比较小。

Minor GC 的频率远高于Major GC,所以对象一旦到达老年代,它存活的时间会更长。


三、实战


在我们查看dump文件的时候,发现内存占用前几名(比例很大)都是日志输出的对象。伪代码如下:

List<XdxDTO> list = this.baseMapper.getAllList();
log.info("当前数据为:{}", JSONUtil.toJsonStr(list));

正常来说在方法里面返回的数据都属于局部变量,当方法执行完毕之后就没有引用会被回收。


但使用log输出的时候,它是异步输出的,消费能力不足的时候,就会把任务丢到阻塞队列里面去,如果某个大对象这时候在阻塞队列等待执行,恰好Edun区满了要被回收的时候,日志还没输出相当于还有引用这个数据,就不会被回收,如果系统持续压力过大,经过几轮Minor GC还没用回收,这个对象就会被放老年代,更难以回收了, 从而导致了内存OOM。

http://www.lryc.cn/news/101770.html

相关文章:

  • 基于扩展(EKF)和无迹卡尔曼滤波(UKF)的电力系统动态状态估计(Matlab代码实现)
  • 曲线拟合(MATLAB拟合工具箱)位置前馈量计算(压力闭环控制应用)
  • 小程序使用echarts
  • 面向对象——封装
  • 【LeetCode】160.相交链表
  • 【JWT的使用】
  • Python获取音视频时长
  • TCP四次握手为什么客户端等待的时间是2MSL
  • Android Studio 启用设备远程调试配置完整步聚
  • 玩转LaTeX(三)【数学公式(基础)、​矩阵、多行公式】
  • jenkins 配置git
  • 单机部署MinIo并设置开机自启
  • Latex | 使用MATLAB生成.eps矢量图并导入Latex中的方法
  • 宝塔面板定时任务重启各种服务
  • Ansible playbook编写
  • 个人博客系统 -- 登录页面添加图片验证码
  • 剑指offer10-I.斐波那契数列
  • 13年测试经验,性能测试-压力测试指标分析总结,看这篇就够了...
  • 大数据课程D3——hadoop的Source
  • F5 LTM 知识点和实验 4-持久化
  • SpringBoot之WebMvcConfigurer详解
  • WPF实战学习笔记22-添加自定义询问窗口
  • Spring Boot项目的创建
  • Python加载数据的5种方法
  • QPoint、QLine、QSize、QRect
  • vue+leaflet笔记之地图量测
  • “深入理解SpringBoot:从入门到精通的几个关键要点“
  • 数值线性代数: 共轭梯度法
  • 【JVM】详解对象的创建过程
  • 华纳云:ubuntu下如何搭建nfs服务