常见原因
- 内存分配过小,与实际业务需要空间不符。
- 对象频繁被创建,却没有被释放,导致内存泄漏。
- 有限系统资源(线程、网络连接)被不断的申请,导致系统资源被耗尽。
问题排查
查看内存分配空间
获取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 2248Attaching to process ID 2248, please wait...Debugger attached successfully.Client compiler detected.JVM version is 24.55-b03using thread-local object allocation.Mark Sweep Compact GCHeap 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% usedEden Space: capacity = 18022400 (17.1875MB) used = 10298688 (9.82159423828125MB) free = 7723712 (7.36590576171875MB) 57.14382102272727% usedFrom Space: capacity = 2228224 (2.125MB) used = 1479976 (1.4114151000976562MB) free = 748248 (0.7135848999023438MB) 66.41953412224265% usedTo Space: capacity = 2228224 (2.125MB) used = 0 (0.0MB) free = 2228224 (2.125MB) 0.0% usedtenured generation: capacity = 44761088 (42.6875MB) used = 21501792 (20.505706787109375MB) free = 23259296 (22.181793212890625MB) 48.03679481606881% usedPerm Generation: capacity = 18874368 (18.0MB) used = 18696632 (17.83049774169922MB) free = 177736 (0.16950225830078125MB) 99.05832078721788% used12663 interned Strings occupying 1650096 bytes.
对堆内存的使用情况进行分析,可以作为内存是否分配过小的依据。
寻找最耗内存的对象
查看方法(线上环境一定要慎用,该命令会导致jvm进行一次full GC):
[root@hostname ~]# jmap -histo:live 2248 | less
结果样例:
num #instances #bytes class name---------------------------------------------- 1: 53225 65494402: 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 2248java(2248)─┬─{java}(2279) ├─{java}(2285) ├─{java}(2286) ├─{java}(2287) ├─{java}(2290) ├─{java}(2291) ├─{java}(2292)...为节约篇幅省略
统计线程数:
[root@hostname ~]# pstree -p 2248 | wc -l42
查看网络连接:
[root@hostname ~]# netstat -naput | grep 2248tcp 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 :::*