StatckOverflowError和OutofMemorryError的区别

来源:互联网 发布:触摸交互式软件 编辑:程序博客网 时间:2024/06/02 02:10

          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

原创粉丝点击