一、简介

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命令内存详情相关推荐

  1. Java的jmap命令使用详解

    jmap命令简介 jmap(Java Virtual Machine Memory Map)是JDK提供的一个可以生成Java虚拟机的堆转储快照dump文件的命令行工具.除此以外,jmap命令还可以查 ...

  2. java: jmap 查看内存信息

    命名行格式 jmap [ option ] pid jmap [ option ] executable core jmap [ option ] [server-id@]remote-hostnam ...

  3. java jmap jc_利用jmap命令查看JVM内存使用详情

    介绍 打印出某个java进程(使用pid)内存内的,所有'对象'的情况(如:产生那些对象,及其数量).它的用途是为了展示java进程的内存映射信息,或者堆内存详情. 可以输出所有内存中对象的工具,甚至 ...

  4. java 命令: jmap 命令使用 ( 查看内存使用、设置 )

    jdk安装后会自带一些小工具,jmap命令(Java Memory Map)是其中之一.主要用于打印指定Java进程(或核心文件.远程调试服务器)的共享对象内存映射或堆内存细节. jmap命令可以获得 ...

  5. jmap java opts_jmap --查看JVM内存使用详情

    概述 命令jmap是一个多功能的命令.它可以生成 java 程序的 dump 文件, 也可以查看堆内对象示例的统计信息.查看 ClassLoader 的信息以及 finalizer 队列. jmap命 ...

  6. java jmap用法_java命令--jmap命令使用

    jdk安装后会自带一些小工具,jmap命令(Java Memory Map)是其中之一.主要用于打印指定Java进程(或核心文件.远程调试服务器)的共享对象内存映射或堆内存细节. jmap命令可以获得 ...

  7. java命令--jmap命令使用

    https://www.cnblogs.com/kongzhongqijing/articles/3621163.html jdk安装后会自带一些小工具,jmap命令(Java Memory Map) ...

  8. jstack(查看线程)、jmap(查看内存)和jstat(性能分析)命令

    转载自  jstack(查看线程).jmap(查看内存)和jstat(性能分析)命令 1.Jstack  1.1   jstack能得到运行java程序的java stack和native stack ...

  9. jmap命令(Java Memory Map)

    JDK内置工具使用 一.javah命令(C Header and Stub File Generator) 二.jps命令(Java Virtual Machine Process Status To ...

最新文章

  1. transformer 系列语音识别
  2. 字符串移位:如“abcdefghi”右移2位后变成“cdefghiab”
  3. vc 中对对话框的几种操作
  4. Windows Server 2008 R2 负载平衡入门篇
  5. Java中类变量(静态变量)和实例变量区别
  6. 计算机电源插头有哪几种,盘点电连接器常见的使用类型
  7. 简单的Site to site ipsec ×××实验
  8. 为什么要学习 Spring Boot?
  9. upload.render多文件上传怎么实现一次性上传多个文件_照片和视频怎么检索?请使用属性查询...
  10. 搭建php环境,更换织梦服务器
  11. OpenDDS简单示例,轻松入门
  12. 论文图表录 出现几个 错误标签未定义的简单解决方法
  13. 经典谢幕千千静听(最终版本)7.0.4 去广告增强版下载
  14. 关于对《上海市人民政府办公厅关于执行〈上海市非营业性客车额度拍卖管理规定〉若干要求的通知》的政策解读...
  15. 微信小程序的图片预加载处理
  16. Cadillac CTS-V
  17. iframe嵌套微信公众号文章
  18. 程序化广告(三)- 程序化广告生态链介绍如DSP/ADX/DMP等
  19. 在Quatrus 9.0环境下实现4位比较器(bdf文件实现)
  20. 如何写好简历中的“个人总结”部分?

热门文章

  1. unity3D 中的空气墙可以进行缩放吗
  2. OpenGL ES EGL TLS(线程局部存储) G3D
  3. 【连续介质力学】张量的性质2
  4. uniqueidentifier数据类型讲解
  5. mysql排序convert_MYSQLVARCHAR排序CAST,CONVERT函数类型转换
  6. PHP文字游戏源码寻仙纪 源码搭建
  7. 使用awk命令分析nginx日志定位响应慢的java接口
  8. [QQAI机器人]-文言文交互式编程
  9. 共享WiFi码推广技巧分享。
  10. 球半预测WNBA :凤凰城水银VS 明尼苏达天猫