jmap(JVM Memory Map)命令用于生成heap dump文件,如果不使用这个命令,还可以使用-XX:+HeapDumpOnOutOfMemoryError参数来让虚拟机出现OOM的时候·自动生成dump文件。jmap不仅能生成dump文件,还可以查询finalize执行队列、Java堆和永久代的详细信息,如当前使用率、当前使用的是哪种收集器等

  options参数:

  1. <no option> #如果不使用选项,则jmap命令将打印共享对象映射。 对于在目标JVM中加载的每个共享对象,将打印起始地址,映射的大小以及共享对象文件的完整路径。 此行为与Oracle Solaris pmap实用程序类似。
  2. -dump:[live,] format=b, file=filename #将hprof二进制格式的Java堆转储为文件名。实时子选项是可选的,但是指定时,只有堆中的活动对象被转储。 要浏览堆转储,可以使用jhat命令来读取生成的文件。
  3. -finalizerinfo #打印正在等待确定的对象的信息。显示在F-Queue队列等待Finalizer线程执行finalizer方法的对象。
  4. -heap #显示堆中对象的统计信息。打印所使用的垃圾收集的堆摘要,头配置和生成智能堆使用情况。 另外,打印字符串的数量和大小。
  5. -histo[:live] #显示堆中对象的统计信息。打印堆的直方图。对于每个Java类,将打印对象的数量,以字节为单位的内存大小以及完全限定的类名称。JVM内部类名称以星号(*)前缀打印。如果指定了活动子选项,则只对活动对象进行计数。
  6. -clstats #打印Java堆的类加载器明智的统计信息。 对于每个类加载器,它的名字,它的活跃程度,地址,父类加载器,以及它所加载类的数量和大小都被打印出来。
  7. -F #当-dump没有响应时,强制生成dump快照。
  8. -h/-help #打印帮助信息。
  9. -Jflag #将标志传递到正在运行jmap命令的Java虚拟机。

jmap -dump:live,format=b,file=dump.hprof 6483  #dump堆到文件,format指定输出格式,live指明是活着的对象,file指定导出的文件名,最后是pid

  Attaching to process ID 5840, please wait...
  Debugger attached successfully.
  Server compiler detected.
  JVM version is 25.161-b12

  using thread-local object allocation.
  Parallel GC with 4 thread(s) #CG方式Heap Configuration: #堆内存初始化配置

  Heap Configuration:
    MinHeapFreeRatio = 0 #对应jvm启动参数-XX:MinHeapFreeRatio设置JVM堆最小空闲比率(default 40)
    MaxHeapFreeRatio = 100 #对应jvm启动参数 -XX:MaxHeapFreeRatio设置JVM堆最大空闲比率(default 70)
    MaxHeapSize = 268435456 (256.0MB) #对应jvm启动参数-XX:MaxHeapSize=设置JVM堆的最大大小
    NewSize = 44564480 (42.5MB) #对应jvm启动参数-XX:NewSize=设置JVM堆的‘新生代’的默认大小
    MaxNewSize = 89128960 (85.0MB) #对应jvm启动参数-XX:MaxNewSize=设置JVM堆的‘新生代’的最大大小
    OldSize = 89653248 (85.5MB) #对应jvm启动参数-XX:OldSize=<value>:设置JVM堆的‘老生代’的大小
    NewRatio = 2 #对应jvm启动参数-XX:NewRatio=:‘新生代’和‘老生代’的大小比率
    SurvivorRatio = 8 #对应jvm启动参数-XX:SurvivorRatio=设置年轻代中Eden区与Survivor区的大小比值
    MetaspaceSize = 21807104 (20.796875MB) 
    CompressedClassSpaceSize = 1073741824 (1024.0MB) 
    MaxMetaspaceSize = 17592186044415 MB 
    G1HeapRegionSize = 0 (0.0MB)   #堆内存使用情况PS Young Generation

  Heap Usage:
  PS Young Generation
  Eden Space: #Eden区内存分布
    capacity = 88080384 (84.0MB)   #Eden区总容量
    used = 74798440 (71.3333511352539MB)  #Eden区已使用
    free = 13281944 (12.666648864746094MB)  #Eden区剩余容量
    84.92065611339751% used   #Eden区使用比率From Space: #其中一个Survivor区的内存分布
  From Space: #from区内存分布   
    capacity = 524288 (0.5MB)  #From区总容量
    used = 0 (0.0MB)  
    free = 524288 (0.5MB)
    0.0% used
  To Space:  #To区内存分布
    capacity = 524288 (0.5MB)  
    used = 0 (0.0MB)
    free = 524288 (0.5MB)
    0.0% used
  PS Old Generation  #老生代内存分布
  capacity = 179306496 (171.0MB)  
  used = 54222168 (51.710289001464844MB)
  free = 125084328 (119.28971099853516MB)
  30.239935088575933% used

  37761 interned Strings occupying 3808632 bytes.

 jmap -histo:live 6483|more

  

java jmap导出dump jmap 生成dump_JVM

 

Jhat

  jhat(JVM Heap Analysis Tool)命令是与jmap搭配使用,用来分析jmap生成的dump,jhat内置了一个微型的HTTP/HTML服务器,生成dump的分析结果后,可以在浏览器中查看。在此要注意,一般不会直接在服务器上进行分析,因为jhat是一个耗时并且耗费硬件资源的过程,一般把服务器生成的dump文件复制到本地或其他机器上进行分析。

  1. [ options ] heap-dump-file
  2. #options : 命令行选项。
  3. #heap-dump-file : 要解析的Java堆转储文件

  OPTIONS选项:

  1. -stack false|true #关闭跟踪对象分配调用堆栈。 如果分配站点信息在堆转储中不可用,则必须将此标志设置为false。 默认值是true。
  2. -refs false|true #关闭对象引用跟踪(tracking of references to objects)。默认值为true.默认情况下, 返回的指针是指向其他特定对象的对象,如反向链接或输入引用(referrers or incoming references), 会统计/计算堆中的所有对象。
  3. -port port-number #设置jhat HTTP服务器的端口。 默认值是7000。
  4. -exclude exclude-file #指定一个列出应该从可达对象查询中排除的数据成员的文件。例如,如果文件列出了java.lang.String.value,那么只要计算出可以从特定Object o 访问的对象列表,则不会考虑涉及java.lang.String.value字段的引用路径。
  5. -baseline exclude-file #指定一个基准堆转储(baseline heap dump)。 在两个 heap dumps 中有相同 object ID 的对象会被标记为不是新的(marked as not being new). 其他对象被标记为新的(new). 在比较两个不同的堆转储时很有用.
  6. -debug int #设置此工具的调试级别。 0级意味着没有调试输出。 为更详细的模式设置更高的值。
  7. -version #报告版本号并退出。
  8. -h/-help #显示帮助信息并退出。
  9. -Jflag #因为jhat 命令实际上会启动一个JVM来执行, 通过 -J 可以在启动JVM时传入一些启动参数. 例如, -J-Xmx512m 则指定运行 jhat 的Java虚拟机使用的最大堆内存为 512 MB. 如果需要使用多个JVM启动参数,则传入多个 -Jxxxxxx.

   jhat -J-Xmx512m dump.hprof 

    #中间的-J-Xmx512m是在dump快照很大的情况下分配512M内存去启动HTTP服务器,运行完之后就可在浏览器打开Http://localhost:7000进行快照分析堆快照分析主要在最后面的Heap Histogram里,里面根据class列出了dump的时候所有存活对象。

    分析同样一个dump快照,MAT需要的额外内存比jhat要小的多的多,所以建议使用MAT来进行分析,当然也看个人偏好。

    

java jmap导出dump jmap 生成dump_JVM_02

 


     具体排查时需要结合代码,观察是否大量应该被回收的对象在一直被引用或者是否有占用内存特别大的对象无法被回收。一般情况,转储文件会down到客户端用工具来分析。