用jmap分析java程序

之前的随笔提到用jstack分析java线程情况,也是在这个项目中,当线程的问题解决之后,发现程序的内存一直增长,于是用jmap工具分析了一下java程序占用内存的情况。

命令很简单,直接

jmap -histo 22955 > jmap.info

其中22955是java的pid,重定向到jmap.info文件中,其内容为:

 num     #instances         #bytes  class name
----------------------------------------------
   1:        585569      359014728  [C
   2:         95905       14389200  <constMethodKlass>
   3:        579358       13904592  java.lang.String
   4:         95905       12287600  <methodKlass>
   5:          8542       10324824  <constantPoolKlass>
   6:         21015        7564272  [B
   7:          8542        6355376  <instanceKlassKlass>
   8:          7126        5664512  <constantPoolCacheKlass>
   9:         53877        5603208  com.wisdombud.unicom.monitor.po.MessageBean
  10:        117112        2810688  java.util.Date
  11:         46743        2534632  [Ljava.lang.Object;
  12:          3669        2142176  <methodDataKlass>
  13:         25046        1850544  [Ljava.util.Hashtable$Entry;
  14:         51662        1653184  java.util.Hashtable$Entry
  15:         50881        1628192  java.util.concurrent.ConcurrentHashMap$HashEntry
  16:         43410        1389120  java.util.HashMap$Entry
  17:         55516        1332384  java.util.ArrayList
  18:         24915        1195920  java.util.Hashtable
  19:          8988        1162184  java.lang.Class
  20:         14523        1161840  java.lang.reflect.Method
  21:         21461        1030128  com.sun.org.apache.xerces.internal.dom.AttrNSImpl
  22:         12866         956456  [S
  23:         14959         750072  [[I
  24:          5752         694480  [I
  25:          9667         618688  com.sun.org.apache.xerces.internal.dom.ElementNSImpl
  26:         23097         554328  com.sun.org.apache.xerces.internal.dom.ParentNode$UserDataRecord
  27:         13430         537200  com.sun.org.apache.xerces.internal.dom.TextImpl
  28:          5279         526192  [Ljava.util.concurrent.ConcurrentHashMap$HashEntry;
  29:         15795         505440  com.sun.org.apache.xerces.internal.xni.QName
  30:          3120         476496  [Ljava.util.HashMap$Entry;
  31:         13949         446368  com.wisdombud.unicom.collect.linux.bean.ConfLinuxFileSys
  32:         23464         375424  java.lang.Object
  33:          3774         366032  [Ljava.lang.String;
  34:           429         233376  <objArrayKlassKlass>
  35:          9685         232440  com.sun.org.apache.xerces.internal.dom.AttributeMap
  36:          6981         223392  com.wisdombud.unicom.collect.linux.bean.PerfLinuxFileSys
  37:          4652         223296  java.util.HashMap
  38:          5279         211160  java.util.concurrent.ConcurrentHashMap$Segment
  39:          5512         176384  java.util.concurrent.locks.ReentrantLock$NonfairSync
  40:           243         173016  [Lcom.sun.org.apache.xerces.internal.util.SymbolTable$Entry;
  41:          3159         126360  java.lang.ref.SoftReference
  42:          2516         120768  com.wisdombud.unicom.collect.linux.bean.ConfLinux
  43:          2761         110440  java.util.LinkedHashMap$Entry
  44:          1143         100584  org.snmp4j.Snmp$PendingRequest
  45:          1364          98208  org.snmp4j.mp.StateReference
  46:          2352          94080  com.wisdombud.unicom.collect.linux.bean.PerfLinux
  
Total       2225122      467913224

 

我去掉了很多占用比较小类。

最重要的是后两列,第三列是占用的字节数,第四列是类,关于类,解释如下:

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

参考:http://stackoverflow.com/questions/7913759/what-are-these-objects-in-the-jmap-histogram

 

可以看到,char比较多,但也能定位到自己代码中MessageBean占用比较多,迅速定位到操作此类的方法,在通过分析代码,找到了问题的原因。

jmap可以经常用,比如每10分钟运行一次,通过对比,观察哪些类的占用内存增长比较多。

 

另外,jmap还有dump的参数,其方法如下:

jmap -dump:format=b,file=mem.dat 22955

在这个项目中,dump出来的文件非常大,因为网络的原因没有传过来,所以没有分析。

关于dump的用法,可以参考:http://www.cnblogs.com/ggjucheng/archive/2013/04/16/3024986.html

 

posted @ 2014-12-03 17:37  wardensky  阅读(2345)  评论(0编辑  收藏  举报