StatckOverflowError和OutofMemorryError的区别

          JAVA虚拟机调的结构主要由程序计数器,堆,java栈,方法区和本地方法区组成,其中Java栈的作用是在存储某一个方法在被调用的时候的一些信息。程序在启动一个线程的时候都会先给这个线程分配一个栈,线程在调用一个方法的时候会创建一个栈帧,然后将这个栈帧压入到java栈中,当方法调用完后,再将这个栈帧从java栈中取出来释放掉。栈帧中存入有局部变量表,操作数栈,方法出口等信息。

          如果程序写的不对,java栈会出现两种错:StatckOverfowError和OutofMemorryError。

          StatckOverfowError是请求的深度大于虚拟机java栈的深度时会报这个错误,通俗的说法是一个方法递归调用,不断的调自己,不断的创建栈帧,当所有的栈帧空间大于java虚拟机栈的空间时,就会报这个错误。

           OutofMemorryError是当一个新的线程启动后,发现没有多的内存给这个线程分配存储的空间后才会报OutofMemorryError。

            总结一下这个错误,相同点都是java栈空间不够了锁导致的,不同点是StatckOverfowError已经给分配线程栈了,但压入的栈帧太多,导致空间不足引起的或者是压入一个栈帧,但是这个栈帧的要求空间太大,一下子就给沾满了导致的。OutofMemorryError是开启一个新的线程后,没有多的空间给这个线程分配了。

            下面用两段代码来加深理解       

StatckOverfowError 

package T20131009;
public class StackOverflowTest {
    public static void main(String[] args) {
        method();
    }
    public static void method(){
        for(;;)
            method();
    }
}



OutOfMemoryError

public class StackOverflowErrorMain {
    int threadCount = 0;

    public StackOverflowErrorMain() {
    }

    public void addNewThread(){
        while (true) {
            threadCount++; //线程的数量
            new Thread() {
                @Override
                public void run() {
                    while (true) ; //线程执行不能停
                }
            }.start();
        }
    }

    public static void main(String[] args){
        StackOverflowErrorMain sofem = new StackOverflowErrorMain();
        try {
            sofem.addNewThread();
        }catch (Throwable e){
            System.out.println(sofem.threadCount);
            e.printStackTrace();
        }
    }
}


注意:

1. 在单线程操作中,无论是栈深度无限增加,还是栈帧(每个方法调用执行时都会在栈中创建一个栈帧,用来存储局部变量,操作数栈,动态链表,方法出口等信息)占的空间太大,都出现的是StackOverflowError

2. 不断创建新的线程的实践中会出现OutofMemoryError的错误


参考文档:http://www.cnblogs.com/stefanking/articles/5434043.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值