Java之jmap命令内存详情
一、简介
jmap命令是一个可以输出所有内存中对象的工具,甚至可以将VM 中的heap,以二进制输出成文本。
打印出某个java进程(使用pid)内存内的,所有‘对象’的情况(如:产生那些对象,及其数量)。
64位机上使用需要使用如下方式:
jmap -J-d64 -heap pid
命令格式
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) 连接到远程调试服务
参数说明
> pid: 目标进程的PID,进程编号,可以采用ps -ef | grep java 查看java进程的PID;
> executable: 产生core dump的java可执行程序;
> core: 将被打印信息的core dump文件;
> remote-hostname-or-IP: 远程debug服务的主机名或ip;
> server-id: 唯一id,假如一台主机上多个远程debug服务;
二、 option
(1)dump
-dump:[live,]format=b,file=<filename> 使用hprof二进制形式,输出jvm的heap内容到文件=. live子选项是可选的,假如指定live选项,那么只输出活的对象到文件.
使用例子
jmap -dump:live,format=b,file=myjmapfile.txt 19570
(2) finalizerinfo
-finalizerinfo 打印正等候回收的对象的信息
使用例子
jmap -finalizerinfo 3772
结果
Attaching to process ID 19570, please wait... Debugger attached successfully. Server compiler detected. JVM version is 24.80-b11 Number of objects pending for finalization: 0 (等候回收的对象为0个)
(3) heap
-heap 打印heap的概要信息,GC使用的算法,heap(堆)的配置及JVM堆内存的使用情况.
使用例子
jmap -heap 19570
结果
using parallel threads in the new generation. ##新生代采用的是并行线程处理方式using thread-local object allocation. Concurrent Mark-Sweep GC ##用标记--清理算法回收Heap Configuration: ##堆配置情况,也就是JVM参数配置的结果[平常说的tomcat配置JVM参数,就是在配置这些]MinHeapFreeRatio = 40 ##最小堆使用比例MaxHeapFreeRatio = 70 ##最大堆可用比例MaxHeapSize = 2147483648 (2048.0MB) ##最大堆空间大小NewSize = 268435456 (256.0MB) ##新生代分配大小MaxNewSize = 268435456 (256.0MB) ##最大可新生代分配大小OldSize = 5439488 (5.1875MB) ##老年代大小NewRatio = 2 ##新生代比例SurvivorRatio = 8 ##新生代与suvivor的比例PermSize = 134217728 (128.0MB) ##perm区 永久代大小MaxPermSize = 134217728 (128.0MB) ##最大可分配perm区 也就是永久代大小Heap Usage: ##堆使用情况【堆内存实际的使用情况】New Generation (Eden + 1 Survivor Space): ##新生代(伊甸区Eden区 + 幸存区survior(1+2)空间)capacity = 241631232 (230.4375MB) ##伊甸区容量used = 77776272 (74.17323303222656MB) ##已经使用大小free = 163854960 (156.26426696777344MB) ##剩余容量32.188004570534986% used ##使用比例Eden Space: ##伊甸区capacity = 214827008 (204.875MB) ##伊甸区容量used = 74442288 (70.99369812011719MB) ##伊甸区使用free = 140384720 (133.8813018798828MB) ##伊甸区当前剩余容量34.65220164496263% used ##伊甸区使用情况From Space: ##survior1区capacity = 26804224 (25.5625MB) ##survior1区容量used = 3333984 (3.179534912109375MB) ##surviror1区已使用情况free = 23470240 (22.382965087890625MB) ##surviror1区剩余容量12.43827838477995% used ##survior1区使用比例To Space: ##survior2 区capacity = 26804224 (25.5625MB) ##survior2区容量used = 0 (0.0MB) ##survior2区已使用情况free = 26804224 (25.5625MB) ##survior2区剩余容量0.0% used ## survior2区使用比例PS Old Generation: ##老年代使用情况capacity = 1879048192 (1792.0MB) ##老年代容量used = 30847928 (29.41887664794922MB) ##老年代已使用容量free = 1848200264 (1762.5811233520508MB) ##老年代剩余容量1.6416783843721663% used ##老年代使用比例Perm Generation: ##永久代使用情况capacity = 134217728 (128.0MB) ##perm区容量used = 47303016 (45.111671447753906MB) ##perm区已使用容量free = 86914712 (82.8883285522461MB) ##perm区剩余容量35.24349331855774% used ##perm区使用比例
(4)histo
-histo[:live] 打印每个class的实例数目,内存占用,类全名信息. VM的内部类名字开头会加上前缀”*”. 如果live子参数加上后,只统计活的对象数量.
使用例子
jmap -histo:live 19570
结果
num #instances(实例) #bytes(字节大小) class name(类名)----------------------------------------------1: 65220 9755240 <constMethodKlass>2: 65220 8880384 <methodKlass>3: 11721 8252112 [B4: 6300 6784040 <constantPoolKlass>5: 75224 6218208 [C6: 93969 5163280 <symbolKlass>7: 6300 4854440 <instanceKlassKlass>8: 5482 4203152 <constantPoolCacheKlass>9: 72097 2307104 java.lang.String10: 15102 2289912 [I11: 4089 2227728 <methodDataKlass>12: 28887 1386576 org.apache.velocity.runtime.parser.Token13: 6792 706368 java.lang.Class14: 7445 638312 [Ljava.util.HashMap$Entry;4380: 1 16 com.sun.proxy.$Proxy208 4381: 1 16 sun.reflect.GeneratedMethodAccessor198 4382: 1 16 com.sun.proxy.$Proxy46 4383: 1 16 org.apache.ibatis.ognl.SetPropertyAccessor 4384: 1 16 oracle.jdbc.driver.OracleDriver 4385: 1 16 com.sun.proxy.$Proxy181 4386: 1 16 com.sun.proxy.$Proxy82 4387: 1 16 java.util.jar.JavaUtilJarAccessImpl 4388: 1 16 com.sun.proxy.$Proxy171 4389: 1 16 sun.reflect.GeneratedMethodAccessor136 4390: 1 16 sun.reflect.GeneratedConstructorAccessor22 4391: 1 16 org.elasticsearch.action.search.SearchAction 4392: 1 16 org.springframework.core.annotation.AnnotationAwareOrderComparator Total 1756265 162523736
采用jmap -histo pid > a.log日志将其保存,在一段时间后,使用文本对比工具,可以对比出GC回收了哪些对象。
jmap -dump:format=b,file=outfile 3024可以将3024进程的内存heap输出出来到outfile文件里,再配合MAT(内存分析工具)。
(5)permstat
-permstat 打印 classload 和 jvm heap长久层的信息. 包含每个classloader的名字,活泼性,地址,父classloader和加载的class数量. 另外,内部String的数量和占用内存数也会打印出来.
使用例子
jmap -permstat 19570
结果
Attaching to process ID 19570, please wait... Debugger attached successfully. Server compiler detected. JVM version is 24.80-b11 finding class loader instances ..done. computing per loader stat ..done. please wait.. computing liveness.liveness analysis may be inaccurate ... class_loader classes bytes parent_loader alive? type<bootstrap> 2538 14654264 null live <internal> 0x000000070af968c8 63 399160 0x0000000707db1788 dead org/apache/catalina/loader/WebappClassLoader@0x000000070367d2a8 0x000000070cba7b08 1 3064 0x0000000707e709a8 dead sun/reflect/DelegatingClassLoader@0x0000000702a50b98 0x000000070cba6a38 28 221344 0x0000000707e709a8 dead org/apache/jasperrvlet/JasperLoader@0x0000000705b11878 0x000000070baed8b8 32 297296 0x0000000707e709a8 dead org/apache/jasperrvlet/JasperLoader@0x0000000705b11878 0x000000070919a610 1 3056 0x0000000707e709a8 dead sun/reflect/DelegatingClassLoader@0x0000000702a50b98 0x000000070bdd1e18 1 3064 0x0000000707e709a8 dead sun/reflect/DelegatingClassLoader@0x0000000702a50b98 0x0000000707f1d480 1 3072 null dead sun/reflect/DelegatingClassLoader@0x0000000702a50b98 0x000000070cba7f48 1 1912 0x0000000707e709a8 dead sun/reflect/DelegatingClassLoader@0x0000000702a50b98 0x000000070cba8508 1 3064 0x0000000707e709a8 dead sun/reflect/DelegatingClassLoader@0x0000000702a50b98 0x000000070cba6c40 1 3064 0x0000000707e709a8 dead sun/reflect/DelegatingClassLoader@0x0000000702a50b98 0x000000070bd4c6a0 1 3056 null dead sun/reflect/DelegatingClassLoader@0x0000000702a50b98 0x000000070cba62b0 28 235472 0x0000000707e709a8 dead org/apache/jasperrvlet/JasperLoader@0x0000000705b11878 0x000000070cba77c8 1 3064 0x0000000707e709a8 dead sun/reflect/DelegatingClassLoader@0x0000000702a50b98 0x000000070cba7388 1 3064 0x0000000707e709a8 dead sun/reflect/DelegatingClassLoader@0x0000000702a50b98 0x000000070cba8148 1 3064 0x0000000707e709a8 dead sun/reflect/DelegatingClassLoader@0x0000000702a50b98 0x000000070afd8b60 1 6704 0x0000000707db1788 dead org/apache/catalina/loader/WebappClassLoader@0x000000070367d2a8 0x000000070919a410 1 1888 null dead sun/reflect/DelegatingClassLoader@0x0000000702a50b98 0x000000070bdd05b0 1 1912 null dead sun/reflect/DelegatingClassLoader@0x0000000702a50b98 0x000000070bc848b8 1 3088 0x0000000707db1788 dead sun/reflect/DelegatingClassLoader@0x0000000702a50b98 0x000000070cba64e8 1 1888 0x0000000707e709a8 dead sun/reflect/DelegatingClassLoader@0x0000000702a50b98 0x0000000707f1d2c0 1 3064 0x0000000707db1788 dead sun/reflect/DelegatingClassLoader@0x0000000702a50b98 0x000000070be82e38 1 1912 null dead sun/reflect/DelegatingClassLoader@0x0000000702a50b98 0x000000070cba7908 1 3208 null dead sun/reflect/DelegatingClassLoader@0x0000000702a50b98 .........total = 273 12995 87547304 N/A alive=1, dead=272 N/A
(6)-F
-F 强迫.在pid没有相应的时候使用-dump或者-histo参数. 在这个模式下,live子参数无效.
(7)-h
-h | -help 打印辅助信息
(8)-J
-J 传递参数给jmap启动的jvm.
三、jmap实现原理
通过jmap和jvm之间进行通信,有两种实现方式:attach 和 SA。
1、attach
attach方式,简单来说就是客户端和服务端之间的通信,客户端发送请求,主要逻辑在服务端执行,jmap相当于客户端,JVM相当于服务端。
在JVM中,有一个叫"Attach Listener"的线程,专门负责监听attach的请求,并执行对应的操作。
比如现在执行"jmap -histo:live 5409",一步一步的实现如下:
1、在Jmap.java类的main函数中,对参数进行解析。
2、解析出来参数中有“-histo:live”,则执行histo方法:
"jmap -dump"实现的原理和"jmap -histo"类似,都是通过attach的方式实现,
attach API的实现方式是:
1、客户端连接到目标JVM,向其发出一个类似“inspectheap”命令;
2、目标JVM接收到命令,执行JVM内相关函数,将收集到的结果以文本形式返回;
3、客户端接收到返回的文本并将其显示出来
2、SA
假如执行"jmap -heap 5409",就不会使用attach方式实现了。
在参数解析中,如果参数是"-heap|-heap:format=b|-permstat|-finalizerinfo"中的一种,或者添加了"-F",比如"jmap -histo -F 5409",则使用SA的方式。
SA方式,和attach方式不同的是,相关的主要逻辑都在SA中实现,从JVM中获取数据即可。
可以大概看下"jmap -heap"的实现,对应的实现类是"HeapSummary",内部通过BugSpotAgent工具类attach到目标VM
执行jmap -heap有些时候可能会导致进程变T,一般是有一个线程在等信号量,这时会block住其它所有线程,可以执行kill -CONT <pid>进行恢复,不过还是强烈建议别执行这个命令。
四、java获取内存dump的几种方式
1、获取内存详情:jmap -dump:format=b,file=e.bin pid
这种方式可以用 jvisualvm.exe 进行内存分析,或者采用 Eclipse Memory Analysis Tools (MAT)这个工具
2. 获取内存dump: jmap -histo:live pid
这种方式会先出发fullgc,所有如果不希望触发fullgc 可以使用jmap -histo pid
3.第三种方式:jdk启动加参数
-XX:+HeapDumpBeforeFullGC
-XX:HeapDumpPath=/httx/logs/dump
这种方式会产生dump日志,再通过jvisualvm.exe 或者Eclipse Memory Analysis Tools 工具进行分析
Java之jmap命令内存详情相关推荐
- Java的jmap命令使用详解
jmap命令简介 jmap(Java Virtual Machine Memory Map)是JDK提供的一个可以生成Java虚拟机的堆转储快照dump文件的命令行工具.除此以外,jmap命令还可以查 ...
- java: jmap 查看内存信息
命名行格式 jmap [ option ] pid jmap [ option ] executable core jmap [ option ] [server-id@]remote-hostnam ...
- java jmap jc_利用jmap命令查看JVM内存使用详情
介绍 打印出某个java进程(使用pid)内存内的,所有'对象'的情况(如:产生那些对象,及其数量).它的用途是为了展示java进程的内存映射信息,或者堆内存详情. 可以输出所有内存中对象的工具,甚至 ...
- java 命令: jmap 命令使用 ( 查看内存使用、设置 )
jdk安装后会自带一些小工具,jmap命令(Java Memory Map)是其中之一.主要用于打印指定Java进程(或核心文件.远程调试服务器)的共享对象内存映射或堆内存细节. jmap命令可以获得 ...
- jmap java opts_jmap --查看JVM内存使用详情
概述 命令jmap是一个多功能的命令.它可以生成 java 程序的 dump 文件, 也可以查看堆内对象示例的统计信息.查看 ClassLoader 的信息以及 finalizer 队列. jmap命 ...
- java jmap用法_java命令--jmap命令使用
jdk安装后会自带一些小工具,jmap命令(Java Memory Map)是其中之一.主要用于打印指定Java进程(或核心文件.远程调试服务器)的共享对象内存映射或堆内存细节. jmap命令可以获得 ...
- java命令--jmap命令使用
https://www.cnblogs.com/kongzhongqijing/articles/3621163.html jdk安装后会自带一些小工具,jmap命令(Java Memory Map) ...
- jstack(查看线程)、jmap(查看内存)和jstat(性能分析)命令
转载自 jstack(查看线程).jmap(查看内存)和jstat(性能分析)命令 1.Jstack 1.1 jstack能得到运行java程序的java stack和native stack ...
- jmap命令(Java Memory Map)
JDK内置工具使用 一.javah命令(C Header and Stub File Generator) 二.jps命令(Java Virtual Machine Process Status To ...
最新文章
- transformer 系列语音识别
- 字符串移位:如“abcdefghi”右移2位后变成“cdefghiab”
- vc 中对对话框的几种操作
- Windows Server 2008 R2 负载平衡入门篇
- Java中类变量(静态变量)和实例变量区别
- 计算机电源插头有哪几种,盘点电连接器常见的使用类型
- 简单的Site to site ipsec ×××实验
- 为什么要学习 Spring Boot?
- upload.render多文件上传怎么实现一次性上传多个文件_照片和视频怎么检索?请使用属性查询...
- 搭建php环境,更换织梦服务器
- OpenDDS简单示例,轻松入门
- 论文图表录 出现几个 错误标签未定义的简单解决方法
- 经典谢幕千千静听(最终版本)7.0.4 去广告增强版下载
- 关于对《上海市人民政府办公厅关于执行〈上海市非营业性客车额度拍卖管理规定〉若干要求的通知》的政策解读...
- 微信小程序的图片预加载处理
- Cadillac CTS-V
- iframe嵌套微信公众号文章
- 程序化广告(三)- 程序化广告生态链介绍如DSP/ADX/DMP等
- 在Quatrus 9.0环境下实现4位比较器(bdf文件实现)
- 如何写好简历中的“个人总结”部分?