OutOfMemoryError.jmap随笔浅谈

jmap(查看内存)命令

-bash-4.1# jmap --help
Usage:
    jmap [option] 
        (to connect to running process)
    jmap [option] 
        (to connect to a core file)
    jmap [option] [server_id@]
        (to connect to remote debug server)

where 

在上面有一些命令的解释,和Example.

命令中的参数解释:

option:选项参数,不可同时使用多个选项参数

pid:java进程id,命令ps -ef | grep java获取

executable:产生核心dump的java可执行文件

core:需要打印配置信息的核心文件

remote-hostname-or-ip:远程调试的主机名或ip

server-id:可选的唯一id,如果相同的远程主机上运行了多台调试服务器,用此选项参数标识服务器

options的参数

heap : 显示Java堆详细信息

histo : 显示堆中对象的统计信息

permstat :Java堆内存的永久保存区域的类加载器的统计信息

finalizerinfo : 显示在F-Queue队列等待Finalizer线程执行finalizer方法的对象
dump : 生成堆转储快照
F : 当-dump没有响应时,强制生成dump快照

举个例子:

-bash-4.1# jmap -heap 11187
Attaching to process ID 11187, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.131-b11

using thread-local object allocation.
Parallel GC with 2 thread(s)

Heap Configuration:
   MinHeapFreeRatio         = 0
   MaxHeapFreeRatio         = 100
   MaxHeapSize              = 492830720 (470.0MB)
   NewSize                  = 10485760 (10.0MB)
   MaxNewSize               = 164102144 (156.5MB)
   OldSize                  = 20971520 (20.0MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 0 (0.0MB)

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 72876032 (69.5MB)
   used     = 30822272 (29.3944091796875MB)
   free     = 42053760 (40.1055908203125MB)
   42.29411392760792% used
From Space:
   capacity = 16252928 (15.5MB)
   used     = 5137416 (4.899421691894531MB)
   free     = 11115512 (10.600578308105469MB)
   31.60917220577117% used
To Space:
   capacity = 15728640 (15.0MB)
   used     = 0 (0.0MB)
   free     = 15728640 (15.0MB)
   0.0% used
PS Old Generation
   capacity = 169869312 (162.0MB)
   used     = 112301376 (107.09893798828125MB)
   free     = 57567936 (54.90106201171875MB)
   66.11045554832175% used

42026 interned Strings occupying 4596712 bytes.

jmap -heap [PID]  ( 这里的PID 通过 ps -ef | grep java 来查看当前正在运行的java进程来获取PID )

打印heap的概要信息,GC使用的算法,heap的配置及使用情况,可以用此来判断内存目前的使用情况以及垃圾回收情况

(通过上面打印发现没有PermSize 永生代的初始大小, MaxPermSize永生代的最大大小 , 永久代在JDK8中被完全的移除了。所以永久代的参数-XX:PermSize和-XX:MaxPermSize也被移除了. 永久代移除详情链接 )

jmap -finalizerinfo [PID] 

打印等待回收的对象信息

-bash-4.1# jmap -finalizerinfo 11187
Attaching to process ID 11187, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.131-b11
Number of objects pending for finalization: 0 #说明当前F-QUEUE队列中并没有等待Fializer线程执行finalizer方法的对象。

jmap -histo [PID]

打印堆的对象统计,包括对象数、内存大小等等。

-bash-4.1# jmap -histo 11187
.........中间太多了打印看不见了
序号            实例数量         字节     类名
6599:             1             16  sun.text.normalizer.NormalizerBase$NFCMode
6600:             1             16  sun.text.normalizer.NormalizerBase$NFDMode
6601:             1             16  sun.text.normalizer.NormalizerBase$NFKCMode
6602:             1             16  sun.text.normalizer.NormalizerBase$NFKDMode
6603:             1             16  sun.text.normalizer.NormalizerImpl
6604:             1             16  sun.text.normalizer.NormalizerImpl$AuxTrieImpl
6605:             1             16  sun.text.normalizer.NormalizerImpl$FCDTrieImpl
6606:             1             16  sun.text.normalizer.NormalizerImpl$NormTrieImpl
6607:             1             16  sun.util.calendar.Gregorian
6608:             1             16  sun.util.locale.InternalLocaleBuilder$CaseInsensitiveChar
6609:             1             16  sun.util.locale.provider.AuxLocaleProviderAdapter$NullProvider
6610:             1             16  sun.util.locale.provider.CalendarDataUtility$CalendarWeekParameterGetter
6611:             1             16  sun.util.locale.provider.SPILocaleProviderAdapter
6612:             1             16  sun.util.locale.provider.TimeZoneNameUtility$TimeZoneNameGetter
6613:             1             16  sun.util.resources.LocaleData
6614:             1             16  sun.util.resources.LocaleData$LocaleDataResourceBundleControl
Total       2362889      122539696
-bash-4.1#

注意* jmap -histo:live [pid] 这个命令执行,JVM会先触发gc,然后再统计信息 . 在正式环境慎用.

扩展 : 使用 jmap -histo:live 11187 | grep  normalizer > junbao_HeapDump.txt  (是打印出存活的 过滤出带有 normalizer字样的 堆信息 保存到当前所在层级的 junbao_HeapDump.txt文件中.)

 

jmap -permstat [PID]

打印Java堆内存的永久区的类加载器的智能统计信息。对于每个类加载器而言,它的名称、活跃度、地址、父类加载器、它所加载的类的数量和大小都会被打印。此外,包含的字符串数量和大小也会被打印。

粘贴的事例.非同一台服务.共参考
[root@localhost jdk1.7.0_79]# jmap -permstat 24971
Attaching to process ID 24971, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.79-b02
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
 
   3034    18149440      null      live    
0x000000070a88fbb8  1   3048      null      dead    sun/reflect/DelegatingClassLoader@0x0000000703c50b58
0x000000070a914860  1   3064    0x0000000709035198  dead    sun/reflect/DelegatingClassLoader@0x0000000703c50b58
0x000000070a9fc320  1   3056    0x0000000709035198  dead    sun/reflect/DelegatingClassLoader@0x0000000703c50b58
0x000000070adcb4c8  1   3064    0x0000000709035198  dead    sun/reflect/DelegatingClassLoader@0x0000000703c50b58
0x000000070a913760  1   1888    0x0000000709035198  dead    sun/reflect/DelegatingClassLoader@0x0000000703c50b58
0x0000000709f3fd40  1   3032      null      dead    sun/reflect/DelegatingClassLoader@0x0000000703c50b58
0x000000070923ba78  1   3088    0x0000000709035260  dead    sun/reflect/DelegatingClassLoader@0x0000000703c50b58
0x000000070a88fff8  1   3048      null      dead    sun/reflect/DelegatingClassLoader@0x0000000703c50b58
0x000000070adcbc58  1   1888    0x0000000709035198  dead    sun/reflect/DelegatingClassLoader@0x0000000703c50b58

上述为jmap的基本分析,共本人自己记录学习使用. (本文演示的是使用JDK8演示)

 

找到一篇不错的详细的使用 链接附上.

 

OutOfMemoryError 原因: 常见的有以下几种:

1.内存中加载的数据量过于庞大,如一次从数据库取出过多数据;

2.集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;

3.代码中存在死循环或循环产生过多重复的对象实体;

4.使用的第三方软件中的BUG;

5.启动参数内存值设定的过小;

常见错误提示:

1.tomcat:java.lang.OutOfMemoryError: PermGen space

2.tomcat:java.lang.OutOfMemoryError: Java heap space

3.weblogic:Root cause of ServletException java.lang.OutOfMemoryError

4.resin:java.lang.OutOfMemoryError

5.java:java.lang.OutOfMemoryError

我遇到的是java.lang.OutOfMemoryError: PermGen space

解决:

1.应用服务器提示错误的解决: 把启动参数内存值设置足够大。

2.Java代码导致错误的解决: 重点排查以下几点:

1)检查代码中是否有死循环或递归调用。

2)检查是否有大循环重复产生新对象实体。

3)检查对数据库查询中,是否有一次获得全部数据的查询。一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。因此对于数据库查询尽量采用分页的方式查询。

4 )检查List、MAP等集合对象是否有使用完后,未清除的问题。List、MAP等集合对象会始终存有对对象的引用,使得这些对象不能被GC回收。

 

tomcat中java.lang.OutOfMemoryError: PermGen space异常处理

一、PermGen space PermGen space的全称是Permanent Generation space,是指内存的永久保存区域, 这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中, 它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对 PermGen space进行清理,所以如果你的应用中有很多CLASS的话,就很可能出现PermGen space错误, 这种错误常见在web服务器对JSP进行pre compile的时候。如果你的WEB APP下都用了大量的第三方jar, 其大小 超过了jvm默认的大小(4M)那么就会产生此错误信息了。

解决方法: 手动设置MaxPermSize大小 修改TOMCAT_HOME/bin/catalina.sh 在“echo "Using CATALINA_BASE:   $CATALINA_BASE"”上面加入以下行: JAVA_OPTS="-server -XX:PermSize=64M -XX:MaxPermSize=128m 建议:将相同的第三方jar文件移置到tomcat/shared/lib目录下,这样可以达到减少jar 文档重复占用内存的目的。

回家以后再JDK7的服务器上解决一下 , 就OK了.

你可能感兴趣的:(java,JDK,Tomcat,JVM,jmap)