首页 > 系统相关 >Linux 上使用 MemoryAnalyzer 分析 OOM 原因

Linux 上使用 MemoryAnalyzer 分析 OOM 原因

时间:2024-01-12 16:35:04浏览次数:35  
标签:分析 文件 ConcurrentHashMap MAT OOM 转储 MemoryAnalyzer 内存 Linux

导读:笔者最近生产环境出现了 OOM,通过借助 MemoryAnalyzer 对生成的堆转储文件进行分析并找到内存泄露的原因,这里记录做下分享。

关于 MemoryAnalyzer

笔者采用 Eclipse Memory Analyzer Open Source Project | The Eclipse Foundation (简称 “MAT‘)。它是一款强大的 Java 堆转储分析工具,它可以帮助开发人员诊断和解决 Java 应用程序中的内存问题,在定位内存泄漏、优化内存使用等方面提供了很大的帮助(注意 MAT 从 1.9 版本开始 JDK 需 >= 11 才可运行)。

配置

由于 MAT 在分析时需要将堆转储文件加载到内存中进行分析。因此,使用 MAT 分析堆转储文件时需要足够的可用内存。如果可用内存小于堆转储文件的大小,MAT 可能无法完全加载堆转储文件,导致分析结果不准确或者分析过程无法进行。因此为了确保能够正确地加载和分析堆转储文件,建议将可用内存设置为大于堆转储文件的大小

由于笔者需要分析的堆转储文件大于 20G 左右,本地不足以分析所以将文件放到一台内存足够大的 Linux 服务器上进行分析。

下载并解压 MAT,根据自身场景修改 MemoryAnalyzer.ini 配置文件的 -Xmx 值

-Xmx25600m
分析

执行分析命令如下:

./ParseHeapDump.sh /data/java_pid1.hprof org.eclipse.mat.api:suspects org.eclipse.mat.api:overview org.eclipse.mat.api:top_components
  • .hprof:待分析的堆转储文件
  • org.eclipse.mat.api:suspects:该插件提供了查找可能存在问题的对象的能力,例如内存泄漏等。这个插件会尝试发现某些对象是否可能导致内存泄漏,并给出相关的建议。
  • org.eclipse.mat.api:overview:该插件提供了对堆中所有对象的总体概述,包括对象类型、数量以及占用空间大小等信息。
  • org.eclipse.mat.api:top_components:该插件提供了对 Java 堆中最大的对象组件(也称为“瓶颈”)的诊断能力。它会查找并报告占用最多内存的对象组件,帮助开发人员快速找到可能导致性能问题的对象组件。

执行命令时可以根据自身分析需要指定对应插件即可。

解读

经过一段时间的分析后会生成报告(位于被分析的文件同级目录下),如:

  • java_pid1_Leak_Suspects.zip
  • java_pid1_System_Overview.zip
  • java_pid1_Top_Components.zip

报告不大,我们下载到本地后查看分析即可。这里笔者主要关注 suspects,在本地浏览器打开其 index.html 文件。

Linux 上使用 MemoryAnalyzer 分析 OOM 原因_eclipse

这份报告给出了前三个导致内存泄露的嫌疑对象,我们可以通过点击 Detauls 进去查看详细情况,这里我们进入查看 Problem Suspect 1。

Linux 上使用 MemoryAnalyzer 分析 OOM 原因_内存泄漏_02

Shortest Paths To the Accumulation Point

报告的概述中提到了 ConcurrentHashMap 存在泄漏嫌疑,在 Shortest Paths To the Accumulation Point 中列出导致内存泄漏的最短路径,并指示内存泄漏点(称为“积累点”)。这些积累点是应用程序中未释放的内存对象,并且它们导致了内存泄漏问题。

Linux 上使用 MemoryAnalyzer 分析 OOM 原因_eclipse_03

Accumulated Objects in Dominator Tree

结合查看 Dominator tree 可以看到内存主要是被 HystrixPropertiesFactory 下的 ConcurrentHashMap 支配(Retained Heap)。

再通过结合代码分析得出泄露原因:在改造连接器时代码设计不当,导致不断往 ConcurrentHashMap 中不断插入元素,导致 ConcurrentHashMap 进行多次扩容操作,从而占用大量内存空间,导致内存泄露。具体为当 ConcurrentHashMap 中元素数量超过某个阈值时,就需要对其进行扩容。默认情况下,ConcurrentHashMap 在每个 Segment 的负载因子达到 0.75 时会自动扩容,将 Segment 中的 Hash 表大小翻倍,以便能够容纳更多的键值对。在扩容过程中,ConcurrentHashMap 会创建新的数组,然后将原来的键值对重新散列到新的数组中。这个过程可能会涉及到大量的内存分配和数据复制操作,很容易导致内存溢出。

标签:分析,文件,ConcurrentHashMap,MAT,OOM,转储,MemoryAnalyzer,内存,Linux
From: https://blog.51cto.com/u_16514774/9219034

相关文章

  • 一个脚本打包三个平台的linux,mac,windows的golang程序
    一个脚本打包三个平台的linux,mac,windows的golang程序:#!/bin/bash#设置变量APP_NAME="atmp"VERSION="1.0.0"BUILD_TIME=$(date+%Y-%m-%d_%H:%M:%S)BUILD_DIR="bin"PLATFORMS=("linux/amd64""windows/amd64""darwin/amd64&......
  • BCLinux 8.2安装配置图解教程--龙蜥社区国产移动云系统
    社区镜像下载地址:https://openanolis.cn/download安装参考地址:https://www.osyunwei.com/archives/13017.html1安装系统界面说明:InstallBigCloudEnterpriseLinux8  #安装Testthismedia&installBigCloudEnterprise Linux8#测试安装文件并安装Troubleshooti......
  • linux 如何对外开放端口号
    在Linux服务器上,如果要让外界通过网络连接到服务器,就需要开放相应的端口号。本文将介绍如何在Linux系统中对外开放端口号。步骤:以下是在Linux系统中对外开放端口号的步骤:1.确定要开放的端口号。2.检查端口号是否已经被使用。3.配置防火墙规则以允许入站流量。4.重启防火墙服务。代......
  • Linux系统日志管理
    一、系统日志的作用系统日志记录了系统运行过程中产生的各种信息,如错误信息、警告信息、提示信息等。这些信息对于了解系统的运行状态、诊断故障、保障系统安全等方面具有重要作用。当系统出现问题时,通过查看日志可以快速定位故障原因,便于进行修复。同时,日志可以帮助系统管理员了解......
  • mac下golang打包到Linux上执行报错:No such file or directory
    本地mac打包golang二进制文件到linux服务器报错:-bash:./atmp-linux:Nosuchfileordirectory很奇怪,明明可执行文件在当前目录下,为什么会找不到呢?使用列出动态库依赖的lld(listdynamicdependencies)命令查看了下,发现:lddatmp-linux发现报错:./atmp-linux:errorwhile......
  • 【一文搞定】Linux面试必备20个常用命令
    第一章什么是linux多用户,多任务,支持多线程和多CPU的操作系统,linux的应用领域:免费,稳定,高效的,一般运行在大型服务器上常用目录介绍:[root@localhost~]#的含义:@之前的是当前登录的用户localhost是主机名字~当前所在的位置(所在的目录)~家目录/根目录#的位置是用户标识#是超级用户$普......
  • 在Linux下配置Apache HTTP服务器
    在Linux的世界里,如果说有什么比解决各种“神秘”的故障更让人头疼,那一定就是配置ApacheHTTP服务器了。这不是因为Apache有什么问题,而是因为配置它简直就像解谜游戏,一不留神就会让你陷入无尽的纠结。首先,你需要知道的是,Apache并不是一个“喂我配置文件,我就能运行”的服务。它需要你......
  • 使用Nginx作为反向代理服务器在Linux中的最佳实践
    在Linux环境下,Nginx因其高效性能、稳定性以及丰富的功能集而广泛用于作为反向代理服务器。以下是在Linux中使用Nginx作为反向代理服务器的最佳实践:1.安装与配置首先,确保你的Linux发行版已经安装了Nginx。大多数Linux发行版都提供了Nginx的包管理工具。例如,在基于Debian的系统上,你......
  • Linux Shell接收键盘输入
    1.read命令格式read[选项][变量名]选项:-p“提示信息”:在等待read输入时,输出提示信息-t“秒数”:read命令会一致等待用户输入,使用此选项可以指定等待时间-n“字符数”:read命令只接受指定的字符数,就会执行-s:隐藏输入的数据,适用于机密信息的......
  • 使用curl命令在Linux上进行HTTP请求
    在Linux系统中,curl是一个非常强大的命令行工具,用于发送各种类型的HTTP请求。通过简单的命令,你可以发送GET、POST、PUT、DELETE等请求,以及设置请求头、处理响应等。以下是一些使用curl进行HTTP请求的常见用法和示例。1.发送GET请求最基本的HTTP请求是GET请求,用于从服务器检索数据。......