JVM内存溢出常见原因分析及排查

为什么80%的码农都做不了架构师?>>>   hot3.png

常见原因

  • 内存分配过小,与实际业务需要空间不符。
  • 对象频繁被创建,却没有被释放,导致内存泄漏。
  • 有限系统资源(线程、网络连接)被不断的申请,导致系统资源被耗尽。

问题排查

查看内存分配空间

    获取java进程:

[root@hostname ~]# ps x | grep java | grep -v grep
 2248 ?        Sl     0:37 /usr/local/java/jdk1.7.0_55/bin/java -Xms64M -Xmx1G -Djava.util.logging.config.file=logging.properties -Djava.security.auth.login.config=/usr/local/apache-activemq-5.13.0//conf/login.config -Dcom.sun.management.jmxremote -Djava.awt.headless=true -Djava.io.tmpdir=/usr/local/apache-activemq-5.13.0//tmp -Dactivemq.classpath=/usr/local/apache-activemq-5.13.0//conf:/usr/local/apache-activemq-5.13.0//../lib/ -Dactivemq.home=/usr/local/apache-activemq-5.13.0/ -Dactivemq.base=/usr/local/apache-activemq-5.13.0/ -Dactivemq.conf=/usr/local/apache-activemq-5.13.0//conf -Dactivemq.data=/usr/local/apache-activemq-5.13.0//data -jar /usr/local/apache-activemq-5.13.0//bin/activemq.jar start
 2615 ?        Sl     0:21 /usr/local/java/jdk1.7.0_55/bin/java -Djava.util.logging.config.file=/usr/local/src/apache-tomcat-7.0.47/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/usr/local/src/apache-tomcat-7.0.47/endorsed -classpath /usr/local/src/apache-tomcat-7.0.47/bin/bootstrap.jar:/usr/local/src/apache-tomcat-7.0.47/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/src/apache-tomcat-7.0.47 -Dcatalina.home=/usr/local/src/apache-tomcat-7.0.47 -Djava.io.tmpdir=/usr/local/src/apache-tomcat-7.0.47/temp org.apache.catalina.startup.Bootstrap start

    以2248为例,获取java堆内存信息:

[root@hostname ~]# jmap -heap 2248
Attaching to process ID 2248, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 24.55-b03

using thread-local object allocation.
Mark Sweep Compact GC

Heap Configuration:
   MinHeapFreeRatio = 40
   MaxHeapFreeRatio = 70
   MaxHeapSize      = 1073741824 (1024.0MB)
   NewSize          = 1048576 (1.0MB)
   MaxNewSize       = 4294901760 (4095.9375MB)
   OldSize          = 4194304 (4.0MB)
   NewRatio         = 2
   SurvivorRatio    = 8
   PermSize         = 12582912 (12.0MB)
   MaxPermSize      = 67108864 (64.0MB)
   G1HeapRegionSize = 0 (0.0MB)

Heap Usage:
New Generation (Eden + 1 Survivor Space):
   capacity = 20250624 (19.3125MB)
   used     = 11778664 (11.233009338378906MB)
   free     = 8471960 (8.079490661621094MB)
   58.16444964856392% used
Eden Space:
   capacity = 18022400 (17.1875MB)
   used     = 10298688 (9.82159423828125MB)
   free     = 7723712 (7.36590576171875MB)
   57.14382102272727% used
From Space:
   capacity = 2228224 (2.125MB)
   used     = 1479976 (1.4114151000976562MB)
   free     = 748248 (0.7135848999023438MB)
   66.41953412224265% used
To Space:
   capacity = 2228224 (2.125MB)
   used     = 0 (0.0MB)
   free     = 2228224 (2.125MB)
   0.0% used
tenured generation:
   capacity = 44761088 (42.6875MB)
   used     = 21501792 (20.505706787109375MB)
   free     = 23259296 (22.181793212890625MB)
   48.03679481606881% used
Perm Generation:
   capacity = 18874368 (18.0MB)
   used     = 18696632 (17.83049774169922MB)
   free     = 177736 (0.16950225830078125MB)
   99.05832078721788% used

12663 interned Strings occupying 1650096 bytes.

    对堆内存的使用情况进行分析,可以作为内存是否分配过小的依据。

寻找最耗内存的对象

    查看方法(线上环境一定要慎用,该命令会导致jvm进行一次full GC):

[root@hostname ~]# jmap -histo:live 2248 | less

    结果样例:

 num     #instances         #bytes  class name
----------------------------------------------
   1:         53225        6549440  
   2:         14540        5446408  [B
   3:         25896        4873976  [C
   4:         53225        3837240  
   5:          4762        2886816  
   6:          1869        2196520  [I
   7:          4762        1913208  
   8:          3914        1526064  
   9:          5156         617792  java.lang.Class
  10:         24970         599280  java.lang.String
  11:          6981         381064  [S
  12:          7812         371952  [[I
  13:          3247         259760  java.lang.reflect.Method
  14:         10474         251376  java.util.concurrent.ConcurrentHashMap$HashEntry
  15:          4157         198456  [Ljava.lang.Object;
  16:          1135         170712  [Ljava.util.HashMap$Entry;
  17:          3656         116992  java.lang.ref.SoftReference
  18:           377         114608  
  19:          3360         107520  java.util.LinkedHashMap$Entry
  20:           702         101784  [Ljava.util.concurrent.ConcurrentHashMap$HashEntry;
  21:          3935          94440  java.lang.ref.WeakReference
  22:          2374          93168  [Ljava.lang.String;
  23:         10622          84976  java.lang.Object
  24:          3308          79392  java.util.HashMap$Entry
  25:          3195          76680  java.util.ArrayList
  26:          1378          66144  java.beans.MethodDescriptor
  27:          1181          66136  java.util.LinkedHashMap
  28:           677          64992  org.springframework.beans.GenericTypeAwarePropertyDescriptor
  29:           701          44864  java.lang.reflect.Constructor
  30:           696          44544  java.beans.PropertyDescriptor
  31:           862          41376  java.util.HashMap
  32:          1616          38784  java.util.concurrent.locks.ReentrantLock$NonfairSync
  33:          2140          35624  [Ljava.lang.Class;
  34:           336          34944  java.net.SocksSocketImpl
...省略

    定位问题时,主要关注点在instance较多,且内存占用较大的实例或者类,有针对性的进行排查分析。

确认资源是否耗尽

    查看线程数:

[root@hostname ~]# pstree -p 2248
java(2248)─┬─{java}(2279)
           ├─{java}(2285)
           ├─{java}(2286)
           ├─{java}(2287)
           ├─{java}(2290)
           ├─{java}(2291)
           ├─{java}(2292)
...为节约篇幅省略

    统计线程数:

[root@hostname ~]# pstree -p 2248 | wc -l
42

    查看网络连接:

[root@hostname ~]# netstat -naput | grep 2248
tcp        0      0 :::5672                     :::*                        LISTEN      2248/java           
tcp        0      0 :::50284                    :::*                        LISTEN      2248/java           
tcp        0      0 :::61613                    :::*                        LISTEN      2248/java           
tcp        0      0 :::61614                    :::*                        LISTEN      2248/java           
tcp        0      0 :::61616                    :::*                        LISTEN      2248/java           
tcp        0      0 :::1883                     :::*                        LISTEN      2248/java           
tcp        0      0 :::8161                     :::*                        LISTEN      2248/java           
udp        0      0 :::24884                    :::*     

    

转载于:https://my.oschina.net/vbird/blog/1518938

你可能感兴趣的:(JVM内存溢出常见原因分析及排查)