jmap的使用以及内存溢出分析

jmap的使用以及内存溢出分析jmap 的使用以及内存溢出分析 jmap java 内存映像工具 jmap MemoryMapfor 命令用于生成堆转储快照 一般称为 heapdump 或 dump 文件 还有几种方式获取 dump 文件 使用 JVM 参数选项 XX HeapDumpOnOu 参数 可以让虚拟机在 OOM 异常出现之后自动生成 dump 文件 通过 XX HeapDumpPath path 设置 dump 文件路径 有时候 dump 文件比较大的时候可能无法自动导出 这时候就需要使用 jmap dump 手动导

jmap的使用以及内存溢出分析

jmap(java内存映像工具)

jmap(Memory Map for Java)命令用于生成堆转储快照(一般称为heapdump或dump文件)。还有几种方式获取dump文件:使用JVM参数选项-XX:+HeapDumpOnOutOfMemoryError参数,可以让虚拟机在OOM异常出现之后自动生成dump文件,通过-XX:HeapDumpPath=path 设置dump文件路径(有时候dump文件比较大的时候可能无法自动导出,这时候就需要使用jmap -dump手动导出了);通过-XX.+HeapDumpOnCtrlBreak参数则可以使用[Ctrl]+[Break]键让虚拟机生成dump文件;或者在Linux系统下通过Kill -3命令发送进程退出信号,也能拿到dump文件。

jmap的作用并不仅仅是为了获取dump文件,它还可以查询finalize执行队列、Java堆和永久代的详细信息,如空间使用率、当前用的是哪种收集器等。和jinfo命令一样,jmap有不少功能在Windows平台下都是受限的,除了生成dump文件的-dump选项和用于查看每个类的实例、空间占用统计的-histo选项在所有操作系统都提供之外,其余选项都只能在Linux/Solans下使用。官方文档地址

1.1、查看内存使用情况

[root@localhost /]# jmap -heap 9906 Attaching to process ID 9906, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.221-b11 using thread-local object allocation. Mark Sweep Compact GC Heap Configuration: MinHeapFreeRatio = 40 MaxHeapFreeRatio = 70 MaxHeapSize =  (944.0MB) NewSize =  (20.0MB) MaxNewSize =  (314.625MB) OldSize =  (40.0MB) NewRatio = 2 SurvivorRatio = 8 MetaspaceSize =  (20.MB) CompressedClassSpaceSize =  (1024.0MB) MaxMetaspaceSize = 415 MB G1HeapRegionSize = 0 (0.0MB) Heap Usage: New Generation (Eden + 1 Survivor Space): capacity =  (18.0625MB) used =  (5.0844MB) free =  (12.0156MB) 28.046% used Eden Space: capacity =  (16.0625MB) used =  (4.8125MB) free =  (11.1875MB) 28.681% used From Space: capacity =  (2.0MB) used =  (0.17188MB) free =  (1.82812MB) 25.5938% used To Space: capacity =  (2.0MB) used = 0 (0.0MB) free =  (2.0MB) 0.0% used tenured generation: capacity =  (40.0MB) used =  (34.094MB) free =  (5.90625MB) 86.734% used 31688 interned Strings occupying  bytes. 

1.2、查看内存中对象数量及大小

#查看所有对象,包括活跃以及非活跃的 jmap -histo <pid> | more #查看活跃对象 jmap -histo:live <pid> | more [root@localhost /]# jmap -histo:live 9906 | more num #instances #bytes class name ---------------------------------------------- 1: 72627  [C 2: 12052  [I 3: 3709  [B 4: 71294  java.lang.String 5: 14306  java.lang.reflect.Method 6: 8153  java.lang.Class 7: 26390  java.util.HashMap$Node 8: 23271  java.util.concurrent.ConcurrentHashMap$Node 9: 10490  [Ljava.lang.Object; 10: 5128  [Ljava.util.HashMap$Node; #对象说明 B byte C char D double F float I int J long Z boolean [数组,如[I表示int[] [L+类名 其他对象 

1.3、将内存使用情况dump到文件中

#用法: jmap -dump:format=b,file=dumpFileName <pid> #示例 [root@localhost /]# jmap -dump:format=b,file=/cfile/dump.dat 9906 Dumping heap to /cfile/dump.dat ... Heap dump file created 

在这里插入图片描述

1.4、通过jhat对dump文件进行分析

jvm的内存dump到文件中,这个文件是一个二进制的文件,不方便查看,可以借助于jhat工具进行查看。

#用法: jhat -port <port> <file> #示例 [root@localhost cfile]# jhat -port 8888 /cfile/dump.dat Reading from /cfile/dump.dat... Dump file created Thu Aug 19 11:31:02 CST 2021 Snapshot read, resolving... Resolving  objects... Chasing references, expect 95 dots............................................................................................... Eliminating duplicate references............................................................................................... Snapshot resolved. Started HTTP server on port 8888 Server is ready. 

打开浏览器进行访问:ip+端口(8888)
在这里插入图片描述

在最后面有OQL查询功能。

在这里插入图片描述

进入页面,输入下面语句查询字符串大于10000,点击Execute按钮,查询结果:

select s from java.lang.String s where s.value.length >= 10000 

在这里插入图片描述

2、通过MAT工具对dump文件进行分析(官网)

MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速、功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。使用内存分析工具从众多的对象中进行分析,快速的计算出在内存中对象的占用大小,看看是谁阻止了垃圾收集器的回收工作,并可以通过报表直观的查看到可能造成这种结果的对象。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I9geT1sO-1629355535351)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210819114901423.png)]

2.1、下载安装

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V7GQluyM-1629355535352)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210819134930028.png)]

运行独立版 Memory Analyzer 所需的最低 Java 版本是 Java 11 如果本地安装的JDK是更低版本的可以下载旧版本。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N61htSA0-1629355535352)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210819140452413.png)]

下载完成后解压MemoryAnalyzer-1.8.1.-win32.win32.x86_64.zip,解压后如图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OU9rJl0G-1629355535353)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210819140912714.png)]

2.2、使用方式

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
查看对象以及它的依赖:


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1WdBhgpu-1629355535355)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210819141903120.png)]

查看可能存在内存泄露的分析:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HSgNBWKc-1629355535355)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210819142008106.png)]

3、内存溢出的定位与分析

引起内存溢出的原因有很多种,常见的有以下几种:

  • 内存中加载的数据量过于庞大,如一次从数据库取出过多数据。
  • 集合类中有对对象的引用,使用完后未清空,使得JVM不能回收。
  • 代码中存在死循环或循环产生过多重复的对象实体。
  • 使用的第三方软件中的BUG。
  • 启动参数内存值设定的过小。

内存溢出在实际的生产环境中经常会遇到,如,不断的将数据写入到一个集合中,出现了死循环或者读取超大的文件等等,都可能会造成内存溢出。如果出现了内存溢出,首先我们需要定位到发生内存溢出的环节,并且进行分析,是正常还是非正常情况,如果是正常的需求,就应该考虑加大内存的设置,如果是非正常需求,那么就要对代码进行修改,修复这个bug。

3.1、模拟内存溢出

import java.util.ArrayList; import java.util.List; import java.util.UUID; public class TestJvmOutOfMemory { 
    public static void main(String[] args) { 
    List<Object> list = new ArrayList<>(); for (int i = 0; i < ; i++) { 
    String str = ""; for (int j = 0; j < 1000; j++) { 
    str += UUID.randomUUID().toString(); } list.add(str); } System.out.println("ok"); } } 

为了更快的现实效果,这里使用Idea,设置执行的参数

#在每次发生内存溢出时,JVM会自动将堆转储,dump文件存放在-XX:HeapDumpPath指定的路径下。 -Xms8m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D: 

在这里插入图片描述

测试结果如下:

在这里插入图片描述
导入到MAT工具中进行分析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N0a7OZ1h-1629355535357)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210819144134395.png)]
可以看到,有87.02%的内存由Object[]数组占有,所以比较可疑。


分析:已经有超过87%的内存都被它占有,这种情况是非常有可能出现内存溢出的

查看详情:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4da6MWYn-1629355535358)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210819144329342.png)]
可以看到集合中存储了大量的uuid字符串。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/231529.html原文链接:https://javaforall.net

(0)
上一篇 2025年12月6日 下午8:01
下一篇 2025年12月6日 下午8:22


相关推荐

  • 无锡高新区拟发布12条“养龙虾”政策 最高补贴500万元

    无锡高新区拟发布12条“养龙虾”政策 最高补贴500万元

    2026年3月13日
    2
  • Android CompoundButton[通俗易懂]

    Android CompoundButton[通俗易懂]为什么80%的码农都做不了架构师?>>>…

    2022年5月2日
    48
  • 测试理论面试题

    测试理论面试题1 说一下你们的测试流程没有做过项目的直接介绍下 v 模型 老师上课肯定有讲过 有经验的直接从接到项目 单子后讲自己如何一步步实施测试的 例如你可以回答这样的流程 1 软件开发完成以后 就会把需求规格说明书 软件程序和软件源代码发过来 2 项目经理出测试方案 要使用什么样的测试方法 测试策略 安排测试计划 测试人员 资源 进度的安排 测试的范围和完成的目标 3 测试人员编写和

    2026年3月16日
    2
  • 这三大经典Python面试题,最常被提问[通俗易懂]

    Python学习网有大量免费的Python入门教程,欢迎大家来学习。本文主要给大家介绍几种常用的内置函数,例如:生成器(Generator)、lambda()、filter()、reduce()、map()。

    2022年1月18日
    103
  • 怎么卸载pip重新安装_pip重新安装显示超时

    怎么卸载pip重新安装_pip重新安装显示超时今天不小心把pip给删除了,然后就搜怎么安装。弄了半天才弄好,这边记录一下:首先这个网站给出了安装的方法https://packaging.python.org/tutorials/installing-packages/#use-pip-for-installing全英文,看不懂?那就按照下面的办法。下载一个文件,连接给出了:https://download.csdn.net/do…

    2022年10月18日
    4
  • Windows环境下进行mysql数据库备份[通俗易懂]

    Windows环境下进行mysql数据库备份[通俗易懂]备份功能使用mysqldump进行数据库备份跨主机备份还原数据库Windows定时执行脚本任务使用mysqldump进行数据库备份mysql数据库自带备份命令mysqldump,可对数据库进行备份操作最简单的备份是将数据库备份至本地,生成**.sql文件编写备份脚本文件(创建一个txt文件,写入批处理脚本,再将文件的后缀改为.bat变为批处理脚本文件)remautherBeginnerXiaoremdate:20200814rem******BackupMySQLStart***

    2022年5月6日
    51

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号