java内存越界内存泄漏内存溢出_OutOfMemoryError异常java内存泄漏(Memory Leak)和内存溢出(Memory Overflow)...

java.lang.OutOfMemoryError: Java heap space

Dumping heap to

java_pid10604.hprof ...

Heap dump file created [29234562 bytes in 0.214 secs]

Heap

PSYoungGen total 9216K, used 8154K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)

eden space 8192K, 99% used [0x00000000ff600000,0x00000000ffdf6a10,0x00000000ffe00000)

from space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)

to space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)

ParOldGen total 10240K, used 9292K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)

object space 10240K, 90% used [0x00000000fec00000,0x00000000ff513390,0x00000000ff600000)

Metaspace used 4979K, capacity 5182K, committed 5248K, reserved 1056768K

class space used 591K, capacity 626K, committed 640K, reserved 1048576K

异常分析:

这个异常咱们要借助Memory Analyzer工具来查看内存溢出的是哪一个对象,刷新整个项目,点击根目录下的java_pid10604.hprof,默认是Overview视图,上面是一个显眼的饼图:

54a1936e1cbbccca63beec59192c27ef.png

在这个饼图里面,咱们能够看到有一个可疑对象在总共16.4MB的内存里,它占用了15.5MB的内存,占用了94.5%的内存。

在饼图的左下方,这个报告告诉咱们这个内存溢出发生在main这个线程里面。

接下来咱们固然想知道究竟是哪一个对象干的,那么找到饼图的下方还有一些工具:

8843d7d76d5cc7928483d5760c0da65e.png

点击Histogram连接,打开Histogram视图:

c9b7f74401852ce2bb74eb9c83628877.png

咱们发如今Objets这一栏,最多的一个对象实例居然达到810327个,这个对象类是com.virtual.VirtualTest。那么很清楚了,咱们new出了太多这个类对象,致使垃圾内存溢出。

26043998d985d32135c47c9cf41df84f.png

在dominator_tree视图中,能够看到main线程占用了94.02%的内存

df892e1edcf3429251803b02df4f41b2.png

在上图中,咱们能够看到该.hprof文件存放的路径、大小、生成时间、格式、报告中总共产生多少对象,堆大小(16.4MB)等信息。

例子2

/*** 以Run AS -> Run Configurations运行。

* 并设置 VM arguments参数以下:

* -Xms10m -Xmx10m -XX:+HeapDumpOnOutOfMemoryError

* 注意:-XX:+HeapDumpOnOutOfMemoryError参数将会使项目根目录下产生java_*.hprof文件*/@Testpublic voidtestOutOfMemory2(){

List list = new ArrayList();for(int i=0;i<10000000;i++){

String str= newString();

list.add(str);

}

}

执行代码后,控制台抛出异常以下:

java.lang.OutOfMemoryError: GC overhead limit exceeded

Dumping heap to

java_pid3360.hprof ...

Heap dump file created [12525143 bytes in 0.136 secs]

异常分析:

Sun 官方对此的定义是:“并行/并发回收器在GC回收时间过长时会抛出OutOfMemroyError。过长的定义是,超过98%的时间用来作GC而且回收了不到2%的堆内存。用来避免内存太小形成应用不能正常工做。“

意思就是GC用尽了全力可仍是来不及回收你new出来的那么多string对象,并且list对象愈来愈大,你还往里面塞对象,还让它活着,你还不让我回收,因而……呵呵……我挂了(>﹏<)

可是我抛出这个异常的目的就是在JVM完全死了以前告诉你我挂了,好让你来得及实施一些紧急措施,好比紧急保存之类。

参考文章《java.lang.OutOfMemoryError:GC overhead limit exceeded填坑心得》

http://www.cnblogs.com/hucn/p/3572384.html

总结

到目前为止,我还没能从Eclipse Memory Analyzer工具中发现可以区分出java内存泄漏(Memory Leak)和内存溢出(Memory Overflow)这两种状态的直接证据。

我的理解为:

java内存泄漏(Memory Leak) 当new出不少对象,而GC没法及时回收这些对象时,会致使内存泄漏。

内存溢出(Memory Overflow) 当一个对象长时间存活,且占用内存巨大直接威胁到总内存时,会致使内存溢出。

如下是其它已在JDK1.8版本中再也不报内存溢出的代码:

举例1

/*** 在JDK1.8中不会抛出异常!!!!

* 以Run AS -> Run Configurations运行。 并设置 VM arguments参数以下:

* -Xss128k -XX:+HeapDumpOnOutOfMemoryError

* 注意:-XX:+HeapDumpOnOutOfMemoryError参数将会使项目根目录下产生java_*.hprof文件*/@Testpublic voidtestOutOfMemory_noError() {int stackLength = 1;try{while (true) {

stackLength= stackLength + 1;

System.out.println("stack length ==" +stackLength);

}

}catch(Throwable t) {

System.out.println("stack length : " +stackLength);throwt;

}

}

举例2

/*** 在JDK1.8中不会抛出异常!!!! 可是会使操做系统假死。

* 以Run AS -> Run Configurations运行。 并设置 VM arguments参数以下:

* -Xss2M -XX:+HeapDumpOnOutOfMemoryError

* 注意:-XX:+HeapDumpOnOutOfMemoryError参数将会使项目根目录下产生java_*.hprof文件*/@Testpublic voidtestOutOfMemory_noError2() {while (true) {

Thread t= new Thread(newRunnable() {

@Overridepublic voidrun() {while (true) {

}

}

});

t.start();

}

}

举例3

/*** 在JDK1.8中不会抛出异常!!!!

* 以Run AS -> Run Configurations运行。 并设置 VM arguments参数以下:

* -XX:PermSize=10M -XX:MaxPermSize=10M -XX:+HeapDumpOnOutOfMemoryError

* 注意:-XX:+HeapDumpOnOutOfMemoryError参数将会使项目根目录下产生java_*.hprof文件*/@Testpublic voidtestOutOfMemory_noError3() {

List list = new ArrayList();int i=0;while (true) {

list.add(String.valueOf(i));

}

}

举例4

/*** 在JDK1.8中不会抛出异常!!!!

* 以Run AS -> Run Configurations运行。 并设置 VM arguments参数以下: -Xms10m -Xmx10m

* -XX:PermSize=10M -XX:MaxPermSize=10M -XX:+HeapDumpOnOutOfMemoryError

* 注意:-XX:+HeapDumpOnOutOfMemoryError参数将会使项目根目录下产生java_*.hprof文件*/@Testpublic voidtestOutOfMemory_noError4() {while(true){

Enhancer enhancer= newEnhancer();

enhancer.setSuperclass(this.getClass());

enhancer.setUseCache(false);

enhancer.setCallback(newMethodInterceptor() {

@OverridepublicObject intercept(Object obj, Method method, Object[] args,

MethodProxy proxy)throwsThrowable {returnproxy.invoke(obj, args);

}

});

enhancer.create();

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值