最近在研究JVM优化方面的知识,今天就顺便用JVM的查看工具测试了一下当发生OutOfMemoryError的时候如何通过工具来分析出错原因。
需要的工具Eclipse Memory Analyzer。
1.在eclipse的run argument中输入以下VM参数(关于Xms,Xmx,Xmn的具体含义参考http://unixboy.iteye.com/blog/174173)。设置了堆空间为20M,年轻代为10M。通过参数-XX:+HeapDumpOnOutOfMemoryError指定发生OutOfMemoryError的时候dump下内存(文件名为java_pid〈进程ID〉.hprof)。通过参数 -XX:+PrintGCDetails -Xloggc:gc.log设置程序输出gc的信息到gc.log文件。
2.以下为java代码
package com.fnk.spring.manager;
import java.util.LinkedList;
class TestGC {
public static void main(String[] args) {
LinkedList<String> l = new LinkedList<String>();
while(true){
l.add(new String("Testttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt"));
}
}
}
3. 以下为gc.log文件。
先说一下日志输出的结构:(1.6和1.5略微有一些不同,只是1.6对于时间统计更加细致)
[GC [<collector>: <starting occupancy1> -> <ending
occupancy1>, <pause time1> secs] <starting occupancy3>
-> <ending occupancy3>, <pause time3> secs]
<collector>GC收集器的名称
<starting occupancy1> 新生代在GC前占用的内存
<ending occupancy1> 新生代在GC后占用的内存
<pause time1> 新生代局部收集时jvm暂停处理的时间
<starting occupancy3> JVM Heap 在GC前占用的内存
<ending occupancy3> JVM Heap 在GC后占用的内存
<pause time3> GC过程中jvm暂停处理的总时间
那么第一行数据可以发现发生min GC的时候年轻代从7680K到1272K回收了6408K,堆空间从7680K到7632K回收了48K,说明有6360K的数据被转移到了年老代。
那么第二行数据可以发现发生Full GC的时候年轻代从1272K到0K回收了1272K,年老代从6360K到7629K增多了1269K,堆空间从7632K到7629K回收了3K。
通过观察年老代不断的增多,一直到上限10240K。最后当年轻代的数量达到7679K的时候就发生了outofmemory的错误。
可以发生eden的space是7680K,from和to space的都是1280k。因为from和to的空间不能同时使用,因此可用的年轻代空间是8960K。默认的eden和surver的空间比例是6:1.
0.386: [GC [PSYoungGen: 7680K->1272K(8960K)] 7680K->7632K(19200K), 0.0439756 secs] [Times: user=0.06 sys=0.00, real=0.05 secs]
0.430: [Full GC [PSYoungGen: 1272K->0K(8960K)] [PSOldGen: 6360K->7629K(10240K)] 7632K->7629K(19200K) [PSPermGen: 2059K->2059K(12288K)], 0.0241013 secs] [Times: user=0.01 sys=0.00, real=0.02 secs]
0.460: [Full GC [PSYoungGen: 7680K->5068K(8960K)] [PSOldGen: 7629K->10240K(10240K)] 15309K->15308K(19200K) [PSPermGen: 2059K->2059K(12288K)], 0.0492533 secs] [Times: user=0.05 sys=0.00, real=0.05 secs]
0.512: [Full GC [PSYoungGen: 7680K->7680K(8960K)] [PSOldGen: 10240K->10240K(10240K)] 17920K->17920K(19200K) [PSPermGen: 2065K->2065K(12288K)], 0.0475882 secs] [Times: user=0.05 sys=0.00, real=0.05 secs]
0.559: [Full GC [PSYoungGen: 7680K->7480K(8960K)] [PSOldGen: 10240K->10240K(10240K)] 17920K->17720K(19200K) [PSPermGen: 2065K->2059K(12288K)], 0.0626773 secs] [Times: user=0.06 sys=0.00, real=0.06 secs]
0.622: [Full GC [PSYoungGen: 7680K->7680K(8960K)] [PSOldGen: 10240K->10240K(10240K)] 17920K->17920K(19200K) [PSPermGen: 2059K->2059K(12288K)], 0.0479926 secs] [Times: user=0.05 sys=0.00, real=0.05 secs]
0.671: [Full GC [PSYoungGen: 7680K->7679K(8960K)] [PSOldGen: 10240K->10240K(10240K)] 17920K->17919K(19200K) [PSPermGen: 2059K->2059K(12288K)], 0.0484853 secs] [Times: user=0.05 sys=0.00, real=0.05 secs]
0.719: [Full GC [PSYoungGen: 7679K->7679K(8960K)] [PSOldGen: 10240K->10240K(10240K)] 17919K->17919K(19200K) [PSPermGen: 2059K->2059K(12288K)], 0.0477472 secs] [Times: user=0.05 sys=0.00, real=0.05 secs]
0.767: [Full GC [PSYoungGen: 7679K->7679K(8960K)] [PSOldGen: 10240K->10240K(10240K)] 17919K->17919K(19200K) [PSPermGen: 2059K->2059K(12288K)], 0.0489797 secs] [Times: user=0.06 sys=0.00, real=0.06 secs]
1.892: [Full GC [PSYoungGen: 7679K->0K(8960K)] [PSOldGen: 10240K->137K(10240K)] 17919K->137K(19200K) [PSPermGen: 2059K->2059K(12288K)], 0.0100488 secs] [Times: user=0.02 sys=0.00, real=0.02 secs]
Heap
PSYoungGen total 8960K, used 209K [0x073e0000, 0x07de0000, 0x07de0000)
eden space 7680K, 2% used [0x073e0000,0x07414518,0x07b60000)
from space 1280K, 0% used [0x07b60000,0x07b60000,0x07ca0000)
to space 1280K, 0% used [0x07ca0000,0x07ca0000,0x07de0000)
PSOldGen total 10240K, used 137K [0x069e0000, 0x073e0000, 0x073e0000)
object space 10240K, 1% used [0x069e0000,0x06a02490,0x073e0000)
PSPermGen total 12288K, used 2065K [0x029e0000, 0x035e0000, 0x069e0000)
object space 12288K, 16% used [0x029e0000,0x02be4558,0x035e0000)
4. 通过memery analyzer可以分析出内存泄漏发生在linkedlist
总结:Memery Analyzer是一个很好的分析工具,在程序运行的时候可以通过Jmap dump下内存,然后通过它来分析。
一个问题是,垃圾回收动作何时执行?
- 当年轻代内存满时,会引发一次普通GC,该GC仅回收年轻代。需要强调的时,年轻代满是指Eden代满,Survivor满不会引发GC
- 当年老代满时会引发Full GC,Full GC将会同时回收年轻代、年老代
- 当永久代满时也会引发Full GC,会导致Class、Method元信息的卸载
另一个问题是,何时会抛出OutOfMemoryException,并不是内存被耗空的时候才抛出
- JVM98%的时间都花费在内存回收
- 每次回收的内存小于2%
- 大小: 17.8 KB
- 大小: 36.6 KB
分享到:
相关推荐
Java内存分析工具MAT(Memory Analyzer Tool) 可以解析内存的消耗,定位具体的类,定位问题
解决OutOfMemoryError: PermGen space,过程是痛苦的,结果是舒畅的
java.lang.OutOfMemoryError: Java heap space 解决方法
ant编译时抛出OutOfMemoryError.doc
was6.1+AIX+ORACLE下一次OutOfMemoryError的解决过程,真实环境下一次问题解决的全过程记录,设计范围比较广,希望对相似环境下有相同问题的朋友有些帮助
遭遇OutOfMemoryError 的解决方法。
java.lang.OutOfMemoryError,产生该错误的原因大都出于以下原因: JVM内存过小、程序不严密,产生了过多的垃圾.
java.lang.OutOfMemoryError处理错误
java.lang.OutOfMemoryError: PermGen space 解决方案
tomcat 出现 OutOfMemoryError 的解决方法
报错 java.lang.OutOfMemoryError: PermGen space 报错 java.lang.OutOfMemoryError: Java heap 启动报错java.lang.ClassNotFoundException: 1catalina.org.apache.juli.FileHandler JAVA_OPTS="-server -Xms800m ...
Myeclipse下java.lang.OutOfMemoryError Java heap space的解决
搜集整理关于java错误处理:java.lang.OutOfMemoryError: Java heap space java.lang.OutOfMemoryError: Java heap space 资料整理
java.lang.OutOfMemoryError: PermGen space
java虚拟机OutOfMemoryError:Java heap space堆dump文件,可以直接用来分析。
OutOfMemoryError_8种典型案例分享,定位java内存问题
java解决nested exception is java.lang.OutOfMemoryError Java heap space 解决OOM
java.lang.OutOfMemoryError: Java heap space 解决方法
内存不足OOM java.lang.OutOfMemoryError.