java 内存泄露 jmap_jmap命令 检查内存泄漏

命令介绍

jmap - Prints shared object memory maps or heap memory details for a process, core file, or remote

debug server.

jmap不仅能生成dump文件,还阔以查询finalize执行队列、Java堆和永久代的详细信息,如当前使用率、当前使用的是哪种收集器等。主要的作用是检查内存泄漏、对象创建不合理和销毁等问题

语法:

jmap [ options ] pid

jmap [ options ] executable core

jmap [ options ] [ pid ] server-id@ ] remote-hostname-or-IP

常用选项

-dump:[live,] format=b, file=filename

dump堆使用信息到文件,format指定格式,live指存活的对象,file为文件名

[root@node1 ~]# jmap -dump:live,format=b,file=hprof.dump 2712

2712: Unable to open socket file: target process not responding or HotSpot VM not loaded

The -F option can be used when the target process isnot responding

报错原因:

jvm运行时会生成一个目录hsperfdata_$USER($USER是启动java进程的用户),在linux中默认是/tmp。目录下会有些pid文件,存放jvm进程信息。

jvm相关命令会从这个路径/tmp/hsperfdata_$USER去获取pid的连接信息,我是root用户执行的命令,所以没有pid文件,而对应应用程序里面有

例如:

531c47b8e53cc0d4bfab05a9642339c8.png

adbbff037d2259e9dbd7cffd18670afb.png

cf80458d3aab82521b22cb83cc74062c.png

jmap报错原因:

可能是由于tmpwatch机制,防止/tmp目录里文件过多,系统每天基于此机制删除超过240小时未访问的文件和目录。

jmap和jstack不能正常运行的原因:

因为对应目录里没有pid文件

查看关键配置/etc/cron.daily/tmpwatch:

flags=-umc /usr/sbin/tmpwatch "$flags"

-x /tmp/.X11-unix -x /tmp/.XIM-unix \

-x /tmp/.font-unix -x /tmp/.ICE-unix

-x /tmp/.Test-unix 240 /tmp /usr/sbin/tmpwatch "$flags" 720 /var/tmp

for d in /var/{cache/man,catman}/{cat?,X11R6/cat?,local/cat?};

do if [ -d "$d" ]; then /usr/sbin/tmpwatch "$flags" -f 720 "$d" fi done

解决办法:

1、修改对应应用的Djava.io.tmpdir参数,统一使用/tmp目录。重启应用

2、修改/etc/cron.daily/tmpwatch

/usr/sbin/tmpwatch "$flags" -x /tmp/hsperfdata_* -x /tmp/.X11-unix -x /tmp/.XIM-unix

-x /tmp/.font-unix -x /tmp/.ICE-unix -x /tmp/.Test-unix 240 /tmp

[root@node1 ~]# jmap -F -dump:live,format=b,file=hprof.dump 2712Attaching to process ID 2712, please wait...

Debugger attached successfully.

Server compiler detected.

JVM version is 25.201-b09

Dumping heap to hprof.dump ...

Heap dump file created

dump.hprof这个后缀是为了后续可以直接用MAT(Memory Anlysis Tool)打开。

-finalizerinfo :打印等待回收对象的信息

[root@node1 ~]# jmap -finalizerinfo 2712Attaching to process ID 2712, please wait...

Debugger attached successfully.

Server compiler detected.

JVM version is 25.201-b09

Number of objects pending for finalization: 0可以看到当前F-QUEUE队列中并没有等待Finalizer线程执行finalizer方法的对象。

-heap :打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况,可以用此来判断内存目前的使用情况以及垃圾回收情况

[root@node1 ~]# jmap -heap 2712Attaching to process ID 2712, please wait...

Debugger attached successfully.

Server compiler detected.

JVM version is 25.201-b09

using thread-local objectallocation.

Parallel GC with 2thread(s) # GC方式

Heap Configuration: // 堆内存初始化配置

MinHeapFreeRatio = 0 // 对应jvm启动参数-XX:MinHeapFreeRatio设置JVM堆最小空闲比率(default 40)

MaxHeapFreeRatio = 100 // 对应jvm启动参数 -XX:MaxHeapFreeRatio设置JVM堆最大空闲比率(default 70)

MaxHeapSize = 52428800 (50.0MB) // 对应jvm启动参数-XX:MaxHeapSize=设置JVM堆的最大大小

NewSize = 17301504 (16.5MB) // 对应jvm启动参数-XX:NewSize=设置JVM堆的‘新生代’的默认大小

MaxNewSize = 17301504 (16.5MB) // 对应jvm启动参数-XX:MaxNewSize=设置JVM堆的‘新生代’的最大大小

OldSize = 35127296 (33.5MB) // 对应jvm启动参数-XX:OldSize=:设置JVM堆的‘老生代’的大小

NewRatio = 2 // 对应jvm启动参数-XX:NewRatio=:‘新生代’和‘老生代’的大小比率

SurvivorRatio = 8 // 对应jvm启动参数-XX:SurvivorRatio=设置年轻代中Eden区与Survivor区的大小比值

MetaspaceSize = 21807104 (20.796875MB) // 对应jvm启动参数-XX:PermSize=:设置JVM堆的‘永生代’的初始大小

CompressedClassSpaceSize = 1073741824 (1024.0MB) // 对应jvm启动参数-XX:MaxPermSize=:设置JVM堆的‘永生代’的最大大小

MaxMetaspaceSize = 17592186044415MB

G1HeapRegionSize = 0 (0.0MB)

Heap Usage: // 堆内存使用情况

PS Young Generation

Eden Space: // Eden区内存分布

capacity = 9961472 (9.5MB) // Eden区总容量

used = 3917840 (3.7363433837890625MB) // Eden区已使用

free = 6043632 (5.7636566162109375MB) // Eden区剩余容量

39.32993035567434% used // Eden区使用比率

From Space: // 其中一个Survivor区的内存分布

capacity = 3670016 (3.5MB)

used = 1028528 (0.9808807373046875MB)

free = 2641488 (2.5191192626953125MB)

28.025163922991073%used

To Space: // 另一个Survivor区的内存分布

capacity = 3145728 (3.0MB)

used = 0 (0.0MB)

free = 3145728 (3.0MB)

0.0%used

PS Old Generation // 当前的Old区内存分布

capacity = 35127296 (33.5MB)

used = 27684384 (26.401885986328125MB)

free = 7442912 (7.098114013671875MB)

78.81159995918843%used

20704 interned Strings occupying 2153624 bytes.

-histo :打印堆的对象统计,包括对象数、内存大小等等 (因为在dump:live前会进行full gc,如果带上live则只统计活对象,因此不加live的堆大小要大于加live堆的大小 )

[root@node1 ~]# jmap -F -histo 2656num #instances #bytes Class description

--------------------------------------------------------------------------

1: 526458 45456832 char[]

2: 275076 6601824java.lang.String

3: 44613 5271264 byte[]

4: 215455 5170920java.util.concurrent.ConcurrentSkipListMap$Node

5: 62357 4515576 int[]

6: 109775 2634600java.lang.Double

7: 74848 2395136java.util.HashMap$Node

8: 18442 1880400java.util.HashMap$Node[]

9: 53471 1820904java.lang.Object[]

....

仅仅打印了前10行

xml classname是对象类型,说明如下:

B byteC charD doubleF floatI intJ longZ boolean

[ 数组,如[I表示int[]

[L+类名 其他对象

-F :强制模式。如果指定的pid没有响应,请使用jmap -dump或jmap -histo选项。此模式下,不支持live子选项

另外,jmap命令生成的hprof文件可以使用jhat进行分析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值