java.lang.OutOfMemoryError发生之前和之后...

OutOfMemoryError简单来讲就是JVM没有内存可用啦,具体来讲就是分配的heap空间不能再往里面放新的对象了.
通常来讲造成这种错误的原因主要有:
1,达到了heap所能支持的最大值.
heap空间太小,放不下要new的对象,举一个极端的例子,heap的size是64m,你要new的对象占用的size
为65m.比如业务高峰期发生,加载大的XML dom对象等.
2,"内存泄漏",heap中积累垃圾回收器不能回收的大量对象.
JVM的垃圾回收器会自动回收那些没有任何变量引用的对象,但是如果一个对象已经不使用了,但是还有
变量引用它(由于代码逻辑的错误),比如自己实现的一个缓存(map),对象不断的加进去,没有使用合适的
策略从缓存中清理.
JDK6之后,JAVA提供了很多工具来帮助发现上面的问题.
1,jps:查看有哪些java进程正在运行.
D:\temp>jps
412 Test1
5716 Main
4724
2476 JConsole
2072 Jps
412 Test1是通过 java -cp t1.jar com.test.Test1 命令启动的一个java进程.
2,jmap -dump:file=heap_file_name pid 将某一个java进程的JVM信息dump出来.
如jmap -dump:file=Test1JVM 412,进程412的JVM信息会dump为文件Test1JVM.
3,jhat分析dump的文件,如jhat Test1JVM,然后打开浏览器http://localhost:7000/ 浏览.
4,>jconsole,可以实时观察JVM的运行信息.
5,java运行是指定参数 -XX:+HeapDumpOnOutOfMemoryError在发生OutOfMemoryError的时候将JVM
的信息dump成文件.
下面通过一个例子来观察:
Java代码如下:不断的创建一个对象,并将它放在一个list里面然JVM垃圾回收器不能回收.
public class TObject {
    int[] arr = new int[20000];
}
public class Test1 {
    private List<TObject> list = new ArrayList<TObject>();
    public void test(){

        int i=0;
        while(true){
            try {
                Thread.sleep(100);
                list.add(new TObject());
                i++;
                System.out.println("There are " + i + " objects created");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] aregs){
        new Test1().test();
    }
}
运行上面这个java类Test1,指定heap的大小为32m,在OutOfMemoryError的时候dump jvm信息.
java -Xms32M -Xmx32M -XX:+HeapDumpOnOutOfMemoryError -cp t1.jar com.test.Test1
通过jconsole观察到的内存使用情况如下图:

java运行的控制台打印如下信息:
.....
There are 407 objects created
There are 408 objects created
java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid5436.hprof ...
Heap dump file created [35684233 bytes in 1.525 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
        at com.test.TObject.<init>(TObject.java:28)
        at com.test.Test1.test(Test1.java:38)
        at com.test.Test1.main(Test1.java:47)
运行jhat:
C:\Program Files\Java\jdk1.6.0_3\bin>jhat d:\temp\java_pid5436.hprof
从http://localhost:7000/访问jhat的分析结果

主要看Show instance counts for all classes (excluding platform)        
这时候可以看到这时候JVM中有些什么样的对象,对象的个数.

通过查看References to this object:
可以发现引用class com.test.TObject的为:
References to this object:
java.util.ArrayList@0x24df9c00 (20 bytes) : field elementData
可以发现引用java.util.ArrayList@0x24df9c00的为:
References to this object:
com.test.Test1@0x24df6638 (12 bytes) : field list
这样就可以分析OutOfMemoryError的原因了.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值