导出内存映像文件并使用MAT工具定位内存溢出问题

问题分析

当在生产环境中发生内存溢出时,需要找出内存溢出的问题所在。当处于生产环境中,需要对内存镜像文件进行分析,进而找出导致内存溢出的原因。那么如何来到处内存镜像文件呢。
有两种方法,下面一一介绍。

内存溢出自动导出

-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=./
./表示当发生内存溢出的时候自动到处到当前路径

使用jmap命令手动导出

jmap -dump:format=b,file=heap.hprof 进程ID

演示自动导出
首先设置VM options

-Xmx32M -Xms32M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./
在这里插入图片描述

访问controller

http://localhost:8080/heap

查看异常信息
java.lang.OutOfMemoryError: GC overhead limit exceeded
Dumping heap to ./\java_pid7612.hprof ...
Heap dump file created [43321403 bytes in 0.143 secs]
Exception in thread "http-nio-8080-exec-1" java.lang.OutOfMemoryError: GC overhead limit exceeded
	at java.lang.StringCoding$StringDecoder.decode(StringCoding.java:149)
	at java.lang.StringCoding.decode(StringCoding.java:193)
	at java.lang.String.<init>(String.java:426)
	at java.util.jar.Attributes.read(Attributes.java:418)
	at java.util.jar.Manifest.read(Manifest.java:199)
	at java.util.jar.Manifest.<init>(Manifest.java:69)
	at java.util.jar.JarFile.getManifestFromReference(JarFile.java:199)
查看生成的文件

在这里插入图片描述

演示手动导出:使用jmap

其中-dump中的format和file比较重要
format=b binary format
file= dump heap to

C:\Users\Administrator>jmap -help
Usage:
    jmap [option] <pid>
        (to connect to running process)
    jmap [option] <executable <core>
        (to connect to a core file)
    jmap [option] [server_id@]<remote server IP or hostname>
        (to connect to remote debug server)

where <option> is one of:
    <none>               to print same info as Solaris pmap
    -heap                to print java heap summary
    -histo[:live]        to print histogram of java object heap; if the "live"
                         suboption is specified, only count live objects
    -clstats             to print class loader statistics
    -finalizerinfo       to print information on objects awaiting finalization
    -dump:<dump-options> to dump java heap in hprof binary format
                         dump-options:
                           live         dump only live objects; if not specified,
                                        all objects in the heap are dumped.
                           format=b     binary format
                           file=<file>  dump heap to <file>
                         Example: jmap -dump:live,format=b,file=heap.bin <pid>
    -F                   force. Use with -dump:<dump-options> <pid> or -histo
                         to force a heap dump or histogram when <pid> does not
                         respond. The "live" suboption is not supported
                         in this mode.
    -h | -help           to print this help message
    -J<flag>             to pass <flag> directly to the runtime system

从 7612 com.imooc.monitor_tuning.MonitorTuningApplication 可知进程的ID为7612
然后使用jmap -dump:format=b,file=heap.hprof 7612进行导出

C:\Users\Administrator\Desktop>jps -l
3536 sun.tools.jps.Jps
7712 org.jetbrains.idea.maven.server.RemoteMavenServer
7908 org.jetbrains.jps.cmdline.Launcher
1852
7612 com.imooc.monitor_tuning.MonitorTuningApplication

C:\Users\Administrator\Desktop>jmap -dump:format=b,file=heap.hprof 7612
Dumping heap to C:\Users\Administrator\Desktop\heap.hprof ...
Heap dump file created

C:\Users\Administrator\Desktop>

可以查看,桌面已经生成了heap.hprof文件
在这里插入图片描述

jmap命令的其他参数

option: -heap, -clstats, -dump:, -F

手动导出和自动导出的对比

当内存比较大的时候,自动导出可能会失去作用,所以这时可以使用jmap来手动导出内存镜像文件。
如使用jmap -heap 进程Id查看内存中很多个区块占用的内存

C:\Users\Administrator\Desktop>jmap -heap 7612
Attaching to process ID 7612, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.181-b13

using thread-local object allocation.
Parallel GC with 8 thread(s)

Heap Configuration:
   MinHeapFreeRatio         = 0
   MaxHeapFreeRatio         = 100
   MaxHeapSize              = 33554432 (32.0MB)
   NewSize                  = 11010048 (10.5MB)
   MaxNewSize               = 11010048 (10.5MB)
   OldSize                  = 22544384 (21.5MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 0 (0.0MB)

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 6815744 (6.5MB)
   used     = 6815744 (6.5MB)
   free     = 0 (0.0MB)
   100.0% used
From Space:
   capacity = 2097152 (2.0MB)
   used     = 0 (0.0MB)
   free     = 2097152 (2.0MB)
   0.0% used
To Space:
   capacity = 2097152 (2.0MB)
   used     = 0 (0.0MB)
   free     = 2097152 (2.0MB)
   0.0% used
PS Old Generation
   capacity = 22544384 (21.5MB)
   used     = 22129496 (21.104331970214844MB)
   free     = 414888 (0.39566802978515625MB)
   98.15968358239462% used

13540 interned Strings occupying 1329080 bytes.

C:\Users\Administrator\Desktop>

进行问题定位

MAT分析内存溢出

在eclipse中安装MAT插件,可以参考:https://blog.csdn.net/jiuweideqixu/article/details/99994536

查看对象的数量

Objects表示对象实例的数量。shallow Heap表示结构占用的内存(如List结构实例占用的内存),Retained Heap表示结构中存放的内容占用的内存(如List结构中存放的所有对象User的实例占用的内存)。
在这里插入图片描述

查看是哪一个GC root引用了这个对象

在某个对象的那一栏右击->Merge Shortest Paths to GC Roots->exclude all phantom/weak/soft etc. references
这里只查看强引用
从下图可以看出,tomcat Thread引用了一个MemoryController,MemoryController引用了userList,userList里面就是所有的User对象了。
GC root到某一个对象,排除所有的虚引用,只看强引用。
在这里插入图片描述

查看对象占用的字节数

同样,点击某一个对象,可以进行展开。
在这里插入图片描述

后记

在真正的生产环境中,场景可能要复杂得多,因此,更要使用好MAT工具来进行内存使用情况的分析。通过分别查看对象和数量和对象占用的内存基本上就可以定位出是哪里发生了内存溢出。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值