Java深究2

这一版延续Java深究1中的继续进行相应补充。

1.先看一个问题,什么是Java多态,我们知道面向对象的三大特点,封装,继承,多态,前两者好理解,多态要怎么理解呢?我们可以想象到有了继承关系,那么肯定会出现这种:

class A extends B{
   void eat(){
   }
}
class C extends B{   
   void eat(){
   }
}
所以可以出现:A a = new B(); B b = (B)a;此时的父类A就有多种表现形态了,此时调用a.eat()那么就调用的B类的eat方法。

2.常见OOM现象:

1)Heap区的OOM,OutOfMemorryError.这实际上就是内存泄露,其原因就是Old区域剩余的内存空间大小不足于满足晋升到Old区域的对象的大小。

出现内存泄露有可能的原因是:死循环写入,或者一个全局区域增加数据导致隐藏的数据膨胀,还有一种内存泄露,就是内存可能在某些使用的情况下增加几十字节的空间没释放,刚开始发现可以被GC掉,但是每次GC都会膨胀那么一点,当运行一段时间后,会发现系统运行很慢,原因是系统不停得在做FULL GC,而且每次做FULL GC的时间非常长,因为绝大多数对象存活着,由于标记存活对象需要更多时间,下面这段代码并不会导致内存泄露,但是会导致频繁的Full GC其原因是每次GC完后会释放一点点内存,然后又一下子满了,就会FULL GC,如此不断反复,当FULL GC时间达到一定比例时就会报错。

public class GCtest {

	public static byte[] DEFAULT_BYTES = new byte[12*1024*1024];

	public static void main(String[] args) {
		List<byte[]> temp = new ArrayList<byte[]>();
		while(true){
			temp.add(new byte[1024*1024]);
			if(temp.size()>3){
				temp.clear();
			}
		}

	}

}
运行时JVM参数:-XX:+PrintGCDetails -Xmn5m -Xms20m -Xmx20m
2)通常的我们会使用try{....}catch(Throwable e){....}捕获到这个error,不让其抛到容器顶层来处理,这样可以让进程继续存在。

3)StackOverFlowError,详解见注释。

package com.roy;

/**
 * 方法分派时会分配frame来存放本地变量,后进先出栈、PC寄存器等信息,
 * 如果方法再调用方法,在不断分派的过程中它也会占用十分多的空间。Java
 * 为了控制一个线程栈空间的无休止的增长(例如,死递归),就会设立一个私有栈空间
 * 大小,通常用-Xss来设置,它的默认值会随着版本、操作系统位数不同而发生一些改变
 * 数量级是256KB~1MB,线程栈所占用的不是堆内存,而是Native Memory,若使用超过
 * -Xss就会报StackOverFlowError。
 * @author SAMSUNG
 *
 */
public class StackOverFlowTs {


	public static void main(String[] args) {
		new StackOverFlowTs().testStackOver();
	}

	public void testStackOver(){
		testStackOver();
	}
}
为什么死递归会导致线程栈溢出呢,原因是递归过程中需要记住方法调用过程以及每个方法运行过程中的本地变量,这个称之为 上下文信息,随着内容的增加,就会占用很多的内存空间,JVM是为了控制它的无限增长,才做了安全监测的处理。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值