zoukankan      html  css  js  c++  java
  • jmap命令

    参看原文地址

    1. Java命令学习系列(三)——Jmap
    2. jmap命令

    作用

    jmap主要可以用于打印Java进程的内存映射或堆内存(Heap Dump文件)细节。(如:产生哪些对象,以及数量等)。主要是用在检查内存泄漏、一些严重影响性能的大对象,检查系统中什么对象创建的最多,分析各种对象所占用的大小等。

    什么是堆Dump

    dump文件是进程的内存副本。堆Dump是反映Java堆使用的内存镜像,其中主要包括系统信息、虚拟机属性、完整的线程Dump、所有类和对象的状态等。一般,在内存不足、GC异常等情况下,我们就会怀疑有内存泄漏。这个时候我们就可以制作堆Dump来查看具体情况,分析原因。

    常见内存错误:

    outOfMemoryError 年老代内存不足。
    outOfMemoryError:PermGen Space 永久代内存不足。
    outOfMemoryError:GC overhead limit exceed 垃圾回收时间占用系统运行时间的98%或以上。

    如何使用

    命令格式

    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
    

    option的可选项

    1. <no option> 如果使用不带选项参数的jmap打印共享对象映射,将会打印目标虚拟机中加载的每个共享对象的起始地址、映射大小以及共享对象文件的路径全称。这与Solaris的pmap工具比较相似。
    2. -dump:[live,]format=b,file=<filename> 以hprof二进制格式转储Java堆到指定filename的文 件中 。live子选项是可选的。如果指定了live子选项,堆中只有活动的对象会被转储。想要浏览heapdump, 你 可以使用jhat(Java堆分析工具)读取生成的文件。
    3. -finalizerinfo 打印等待终结的对象信息。
    4. -heap 打印一个堆的摘要信息,包括使用的GC算法、堆配置信息和generation wise heap usage。
    5. -histo[:live] 打印堆的柱状图。其中包括每个Java类、对象数量、内存大小(单位:字节)、完全限定的类名。打印的虚拟机内部的类名称将会带有一个’*’前缀。如果指定了live子选项,则只计算活动的对象。
    6. -permstat 打印Java堆内存的永久保存区域的类加载器的智能统计信息。对于每个类加载器而言,它的名称、活跃度、地址、父类加载器、它所加载的类的数量和大小都会被打印。此外,包含的字符串数量和大小也会被打印。
    7. -F 强制模式。如果指定的pid没有响应,请使用jmap -dump或jmap -histo选项。此模式下,不支持live子 选项。

    使用案例

    查看java堆(heap)使用情况,执行命令:jmap -heap 31846

    Attaching to process ID 31846, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 24.71-b01
    
    using thread-local object allocation.
    Parallel GC with 4 thread(s)//GC 方式
    
    Heap Configuration: //堆内存初始化配置
       MinHeapFreeRatio = 0 //对应jvm启动参数-XX:MinHeapFreeRatio设置JVM堆最小空闲比率(default 40)
       MaxHeapFreeRatio = 100 //对应jvm启动参数 -XX:MaxHeapFreeRatio设置JVM堆最大空闲比率(default 70)
       MaxHeapSize      = 2082471936 (1986.0MB) //对应jvm启动参数-XX:MaxHeapSize=设置JVM堆的最大大小
       NewSize          = 1310720 (1.25MB)//对应jvm启动参数-XX:NewSize=设置JVM堆的‘新生代’的默认大小
       MaxNewSize       = 17592186044415 MB//对应jvm启动参数-XX:MaxNewSize=设置JVM堆的‘新生代’的最大大小
       OldSize          = 5439488 (5.1875MB)//对应jvm启动参数-XX:OldSize=<value>:设置JVM堆的‘老生代’的大小
       NewRatio         = 2 //对应jvm启动参数-XX:NewRatio=:‘新生代’和‘老生代’的大小比率
       SurvivorRatio    = 8 //对应jvm启动参数-XX:SurvivorRatio=设置年轻代中Eden区与Survivor区的大小比值 
       PermSize         = 21757952 (20.75MB)  //对应jvm启动参数-XX:PermSize=<value>:设置JVM堆的‘永生代’的初始大小
       MaxPermSize      = 85983232 (82.0MB)//对应jvm启动参数-XX:MaxPermSize=<value>:设置JVM堆的‘永生代’的最大大小
       G1HeapRegionSize = 0 (0.0MB)
    
    Heap Usage://堆内存使用情况
    PS Young Generation
    Eden Space://Eden区内存分布
       capacity = 33030144 (31.5MB)//Eden区总容量
       used     = 1524040 (1.4534378051757812MB)  //Eden区已使用
       free     = 31506104 (30.04656219482422MB)  //Eden区剩余容量
       4.614088270399305% used //Eden区使用比率
    From Space:  //其中一个Survivor区的内存分布
       capacity = 5242880 (5.0MB)
       used     = 0 (0.0MB)
       free     = 5242880 (5.0MB)
       0.0% used
    To Space:  //另一个Survivor区的内存分布
       capacity = 5242880 (5.0MB)
       used     = 0 (0.0MB)
       free     = 5242880 (5.0MB)
       0.0% used
    PS Old Generation //当前的Old区内存分布
       capacity = 86507520 (82.5MB)
       used     = 0 (0.0MB)
       free     = 86507520 (82.5MB)
       0.0% used
    PS Perm Generation//当前的 “永生代” 内存分布
       capacity = 22020096 (21.0MB)
       used     = 2496528 (2.3808746337890625MB)
       free     = 19523568 (18.619125366210938MB)
       11.337498256138392% used
    
    670 interned Strings occupying 43720 bytes
    

    查看堆内存(histogram)中的对象数量及大小,执行命令:

    1. jmap -histo 3331
    2. jmap -histo 3331 | more 只显示前一页
    3. jmap -histo 3331 | less 只显示前一页
    4. jmap -histo 3331 |head -30 显示前30条
    
    num     #instances         #bytes  class name
    编号     个数                字节     类名
    ----------------------------------------------
       1:             7        1322080  [I
       2:          5603         722368  <methodKlass>
       3:          5603         641944  <constMethodKlass>
       4:         34022         544352  java.lang.Integer
       5:           371         437208  <constantPoolKlass>
       6:           336         270624  <constantPoolCacheKlass>
       7:           371         253816  <instanceKlassKlass>
    

    jmap -histo:live 这个命令执行,JVM会先触发gc,然后再统计信息。

    将内存使用的详细情况输出到文件

    jmap -dump:format=b,file=heapDump 6900
    

    然后用jhat命令可以参看 jhat -port 5000 heapDump 在浏览器中访问:http://localhost:5000/ 查看详细信息.

    这个命令执行,JVM会将整个heap的信息dump写入到一个文件,heap如果比较大的话,就会导致这个过程比较耗时,并且执行的过程中为了保证dump的信息是可靠的,所以会暂停应用。

    总结

    1. 如果程序内存不足或者频繁GC,很有可能存在内存泄露情况,这时候就要借助Java堆Dump查看对象的情况。
    2. 要制作堆Dump可以直接使用jvm自带的jmap命令
    3. 可以先使用jmap -heap命令查看堆的使用情况,看一下各个堆空间的占用情况。
    4. 使用jmap -histo:[live]查看堆内存中的对象的情况。如果有大量对象在持续被引用,并没有被释放掉,那就产生了内存泄露,就要结合代码,把不用的对象释放掉。
    5. 也可以使用 jmap -dump:format=b,file=命令将堆信息保存到一个文件中,再借助jhat命令查看详细内容
    6. 在内存出现泄露、溢出或者其它前提条件下,建议多dump几次内存,把内存文件进行编号归档,便于后续内存整理分析。

    我的总结:

    jmap作用:

    1. 查看堆内存使用情况。
    2. 查看堆内细节:创建了哪些对象以及数量、这些对象占用的堆内存大小。

    常用jmap命令:

    1. jmap -heap pid 查看堆内存使用情况
    2. jmap -histo[:live] pid 查看大对象

    使用场景:

    1. 内存溢出 频繁GC

    2017年12月12日 补充:

    jmap -histo pid 输出的[C [B [I [S methodKlass constantPoolKlass含义

    jmap -histo pid时,我们常见可以看见下面的:

     num     #instances         #bytes  class name  
    ----------------------------------------------  
       1:         31939       98883072  [C  
       2:          8594        9461992  [B  
       3:         30326        4256232  <constMethodKlass>  
       4:         30326        3892592  <methodKlass>  
       5:          2719        3226344  <constantPoolKlass>  
       6:          2450        1948704  <constantPoolCacheKlass>  
       7:          2719        1869200  <instanceKlassKlass>  
       8:         27599         662376  java.lang.String  
       9:           836         442968  <methodDataKlass>  
      10:          8215         394320  org.apache.tomcat.util.buf.ByteChunk  
      11:          3012         366720  java.lang.Class  
      12:         11257         360224  java.util.HashMap$Entry  
      13:          3417         273360  java.lang.reflect.Method  
      14:          6763         270520  java.util.TreeMap$Entry  
      15:          4326         260720  [S  
      16:          5410         259680  org.apache.tomcat.util.buf.MessageBytes  
      17:          6410         256400  org.apache.tomcat.util.buf.CharChunk  
      18:          4558         238352  [[I  
      19:          3347         211512  [Ljava.lang.Object;  
      20:          2144         189280  [I  
      21:           276         147936  <objArrayKlassKlass>  
      22:           948         142216  [Ljava.util.HashMap$Entry;  
      23:          2874         137952  java.util.HashMap  
      24:           621          89424  java.text.DecimalFormat  
      25:          2555          81760  java.util.concurrent.ConcurrentHashMap$HashEntry  
      26:           620          69440  java.util.GregorianCalendar  
      27:          1052          68936  [Ljava.lang.String;  
    

    其中:

    • [C is a char[]
    • [S is a short[]
    • [I is a int[]
    • [B is a byte[]
    • [[I is a int[][]

    上面的输出中[C对象占用Heap这么多,往往跟String有关,String其内部使用final char[]数组来保存数据的。

    constMethodKlass/ methodKlass/ constantPoolKlass/ constantPoolCacheKlass/ instanceKlassKlass/ methodDataKlass 与Classloader相关,常驻与Perm区。

  • 相关阅读:
    git stash错误小记
    PHP,Mysql根据经纬度计算距离并排序
    JS~字符串长度判断,超出进行自动截取(支持中文)
    Redis的三种启动方式
    Ubuntu 14.04 LTS下安装Google Chrome浏览器
    PHP-PHPExcel用法详解
    git设置log的别名 for hist log样式格式化
    Ubuntu系统下配置PHP支持SQLServer 2005
    Git命令图片版
    《一线架构师实践指南》读后感(二)
  • 原文地址:https://www.cnblogs.com/boothsun/p/8027297.html
Copyright © 2011-2022 走看看