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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 就这样CSDN账号被人盗了??

    就这样CSDN账号被人盗了??

    2022年1月19日
    52
  • 基于阿里DDNS的ipv6 for windows版软件「建议收藏」

    基于阿里DDNS的ipv6 for windows版软件「建议收藏」基于阿里DDNS的ipv6forwindows版软件会搜到这篇帖子的同学,应该和我一样,满世界为自己的虚拟主机找寻ipv6的动态ddns程序吧?下面我先说说我的折腾故事:因为买了群晖,然后发现需要公网ip,但公网ip现在电信要钱了,开口100元一个月,挺黑的。没办法尝试了各种内网穿透,这类帖子网上很多,就不细说了,总之是各种折腾,各种不爽,最终选择了零遁伴侣做内网穿透还算稳定,速度也不错。…

    2022年6月13日
    52
  • 服务器推送技术

    服务器推送技术需求与背景之前所有的请求都是浏览器发起,浏览器本身没有接受请求的能力。所以一些特殊需求都是用ajax轮询的方式来实现的。比如:股价展示页面实时的获取股价更新赛事的文字直播,实时更新赛况通过页

    2022年7月3日
    27
  • Nginx负载均衡配置简单配置方法

    Nginx负载均衡配置简单配置方法

    2021年10月9日
    47
  • PyTorch实现MLP的两种方法,以及nn.Conv1d, kernel_size=1和nn.Linear的区别

    PyTorch实现MLP的两种方法,以及nn.Conv1d,kernel_size=1和nn.Linear的区别MLP(Multi-layerperceptron)实现MLP结构方法1:nn.Linear方法2:nn.Conv1d&kernel_size=1nn.Conv1d,kernel_size=1与nn.Linear不同MLP(Multi-layerperceptron)实现最近在看PointNet论文,其主要思想为利用MLP结构学习点云特征,并进行全局池化(构造一个对称函数,

    2022年4月6日
    177
  • CTF流量分析常见题型(二)-USB流量

    CTF流量分析常见题型(二)-USB流量0x00前言在学习Wireshark常见使用时,对常见CTF流量分析题型和铁人三项流量分析题的部分问题进行了简单总结。由于篇幅过长,于是另起一篇总结常见流量包分析。包括USB流量包分析和一些其他流量包分析。0x01USB流量包分析USB流量指的是USB设备接口的流量,攻击者能够通过监听usb接口流量获取键盘敲击键、鼠标移动与点击、存储设备的铭文传输通信、USB无线网卡网络传输内容等等。在CTF中,USB流量分析主要以键盘和鼠标流量为主。1、键盘流量USB协议数据部分在LeftoverCapt

    2022年6月11日
    138

发表回复

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

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