JVM性能调试之jmap

jmap 的用途是为了展示java进程的内存映射信息,或者堆内存详情

常用的参数如下:

histo

jmap -histo pid 展示class的内存情况

展示的信息为编号,实例数,字节,类名

例如:

Java代码  收藏代码
  1. jmap -histo:live 2540  
  2.   
  3.  num     #instances         #bytes  class name  
  4. ----------------------------------------------  
  5.    1:         20981         908120  [C  
  6.    2:         21015         504360  java.lang.String  
  7.    4:          9999         159984  org.learn.util.User  
  8.    5:           312          59216  [Ljava.lang.Object;  

 

heap

 

jmap -heap pid 展示pid的整体堆信息

如:

 

Java代码  收藏代码
  1. $ jmap -heap 29030  
  2. JVM version is 16.3-b01  
  3.   
  4. using thread-local object allocation.  
  5. Parallel GC with 13 thread(s)  
  6.   
  7. Heap Configuration:  
  8.    MinHeapFreeRatio = 40  
  9.    MaxHeapFreeRatio = 70  
  10.    MaxHeapSize      = 8436842496 (8046.0MB)  
  11.    NewSize          = 5439488 (5.1875MB)  
  12.    MaxNewSize       = 17592186044415 MB  
  13.    OldSize          = 5439488 (5.1875MB)  
  14.    NewRatio         = 2  
  15.    SurvivorRatio    = 8  
  16.    PermSize         = 21757952 (20.75MB)  
  17.    MaxPermSize      = 88080384 (84.0MB)  
  18.   
  19. Heap Usage:  
  20. PS Young Generation  
  21. Eden Space:  
  22.    capacity = 87883776 (83.8125MB)  
  23.    used     = 31053080 (29.614524841308594MB)  
  24.    free     = 56830696 (54.197975158691406MB)  
  25.    35.33425782706469% used  
  26. From Space:  
  27.    capacity = 13828096 (13.1875MB)  
  28.    used     = 196608 (0.1875MB)  
  29.    free     = 13631488 (13.0MB)  
  30.    1.4218009478672986% used  
  31. To Space:  
  32.    capacity = 16384000 (15.625MB)  
  33.    used     = 0 (0.0MB)  
  34.    free     = 16384000 (15.625MB)  
  35.    0.0% used  
  36. PS Old Generation  
  37.    capacity = 156172288 (148.9375MB)  
  38.    used     = 27098208 (25.842864990234375MB)  
  39.    free     = 129074080 (123.09463500976562MB)  
  40.    17.35148299805917% used  
  41. PS Perm Generation  
  42.    capacity = 88080384 (84.0MB)  
  43.    used     = 50847592 (48.492042541503906MB)  
  44.    free     = 37232792 (35.507957458496094MB)  
  45.    57.728622073218936% used  

 对应的说明如下:

 

 

Java代码  收藏代码
  1. Parallel GC with 13 thread(s)   #13个gc线程  
  2.   
  3. Heap Configuration:#堆内存初始化配置  
  4.    MinHeapFreeRatio = 40  #-XX:MinHeapFreeRatio设置JVM堆最小空闲比率  
  5.    MaxHeapFreeRatio = 70  #-XX:MaxHeapFreeRatio设置JVM堆最大空闲比率  
  6.    MaxHeapSize      = 8436842496 (8046.0MB)#-XX:MaxHeapSize=设置JVM堆的最大大小  
  7.    NewSize          = 5439488 (5.1875MB) #-XX:NewSize=设置JVM堆的‘新生代’的默认大小  
  8.    MaxNewSize       = 17592186044415 MB  #-XX:MaxNewSize=设置JVM堆的‘新生代’的最大大小  
  9.    OldSize          = 5439488 (5.1875MB) #-XX:OldSize=设置JVM堆的‘老生代’的大小  
  10.    NewRatio         = 2 #-XX:NewRatio=:‘新生代’和‘老生代’的大小比率  
  11.    SurvivorRatio    = 8 #-XX:SurvivorRatio=设置年轻代中Eden区与Survivor区的大小比值  
  12.    PermSize         = 21757952 (20.75MB) #-XX:PermSize=<value>:设置JVM堆的‘永生代’的初始大小  
  13.    MaxPermSize      = 88080384 (84.0MB) #-XX:MaxPermSize=<value>:设置JVM堆的‘永生代’的最大大小  
  14.   
  15. Heap Usage:  
  16. PS Young Generation  
  17. Eden Space:#Eden区内存分布  
  18.    capacity = 87883776 (83.8125MB)  
  19.    used     = 31053080 (29.614524841308594MB)  
  20.    free     = 56830696 (54.197975158691406MB)  
  21.    35.33425782706469% used  
  22. From Space:#其中一个Survivor区的内存分布  
  23.    capacity = 13828096 (13.1875MB)  
  24.    used     = 196608 (0.1875MB)  
  25.    free     = 13631488 (13.0MB)  
  26.    1.4218009478672986% used  
  27. To Space:#另一个Survivor区的内存分布  
  28.    capacity = 16384000 (15.625MB)  
  29.    used     = 0 (0.0MB)  
  30.    free     = 16384000 (15.625MB)  
  31.    0.0% used  
  32. PS Old Generation#当前的Old区内存分布  
  33.    capacity = 156172288 (148.9375MB)  
  34.    used     = 27098208 (25.842864990234375MB)  
  35.    free     = 129074080 (123.09463500976562MB)  
  36.    17.35148299805917% used  
  37. PS Perm Generation#当前的 “永生代” 内存分布  
  38.    capacity = 88080384 (84.0MB)  
  39.    used     = 50847592 (48.492042541503906MB)  
  40.    free     = 37232792 (35.507957458496094MB)  
  41.    57.728622073218936% used  

dump

 

jmap -dump:<dump-options>  pid 把pid的整体堆信息输出

dump-options:

live

format=b

file=<file>

导出的文件可以供分析用,比如jhat或者mat,以便查找内存溢出原因

例如:

Java代码  收藏代码
  1. jmap -dump:live,format=b,file=tomcat.bin 29030  

 

 

 

 

mat为eclipse的一个内存分析插件,帮助查找内存泄漏和减少内存消耗。

首先基于jmap导出的堆信息

jmap导出参见另一则博客

Java代码  收藏代码
  1. jmap -dump:live,format=b,file=test.bin 29030    

 准备代码:

对象:

Java代码  收藏代码
  1. class User {  
  2.     private String id;  
  3.     private String name;  
  4.   
  5.     public String getId() {  
  6.         return id;  
  7.     }  
  8.   
  9.     public void setId(String id) {  
  10.         this.id = id;  
  11.     }  
  12.   
  13.     public String getName() {  
  14.         return name;  
  15.     }  
  16.   
  17.     public void setName(String name) {  
  18.         this.name = name;  
  19.     }  
  20.   
  21.     public User(String id, String name) {  
  22.         super();  
  23.         this.id = id;  
  24.         this.name = name;  
  25.     }  
  26.   
  27. }  

 main方法:

Java代码  收藏代码
  1. public static void main(String[] args) {  
  2.     List<User> list = new ArrayList<User>();  
  3.     for (int i = 1; i < 10000; i++) {  
  4.         User o = new User(i + "", System.currentTimeMillis() + "");  
  5.         list.add(o);  
  6.         o = null;  
  7.     }  
  8.     System.out.println("end");  
  9.     try {  
  10.         Thread.sleep(100000000l);  
  11.     } catch (InterruptedException e) {  
  12.         e.printStackTrace();  
  13.     }  
  14. }  

 执行之后用jmap输出堆信息

然后导入分析工具

我们可以看到图形化展示:



 然后我们点击

Problem Suspect 1

如下所示:



 然后点击详情



 我们可以看到有很多的User对象



 这些对象有可能会溢出,然后我们打开OQL窗口看他是否为null,执行如下OQL语句

Java代码  收藏代码
  1. SELECT u FROM org.learn.util.User u WHERE (u.value = null)  

 结果如下:



 也就是说这个是null,但是仍然有强引用存在,gc的时候是不能回收的,这样就会出现内存的溢出问题

posted on 2013-09-03 13:15  5彩石头  阅读(354)  评论(0)    收藏  举报

导航