日期:2014-05-20  浏览次数:20811 次

Java面试问题之五十二
问题:请分析一下Java中StackOverflowError异常和OutOfMemoryError异常之间联系与区别,什么时候会产生StackOverflowError异常?什么时候产生OutOfMemoryError异常?

答:在Java虚拟机规范中是这样描述这两类异常的:
     (1)如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异
             常;
     (2)如果虚拟机在扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异
             常。
       对于Java虚拟机规范中的描述,对这两种异常有着清晰的区分,但还是存在一些相互重叠的地方:当栈空间无法继续分配的时候,我们不能确定到底时内存大小限制还是栈的最大深度受到限制而抛出异常。
       在单线程的环境中,无论时由于栈帧太大,还是虚拟机容量太小,当内存无法分配时虚拟机总是抛出StackOverflowError异常而不是OutOfMemoryError异常。在多线程的环境中,通过不断建立线程的方式可以产生内存溢出异常。但是,这种方式产生的内存溢出异常与栈空间是否足够并没有什么关系,在这种情况下,给每个线程的栈分配的内存越大,反而越容易产生内存溢出异常。原因主要是:每个线程分配到的栈容量越大,可以建立的线程数量自然就越少,建立线程时就越容易把剩下的内存耗尽。如果是建立过多的线程导致内存溢出,在不能减少线程数或者更换64位虚拟机的情况下,就只能通过减少最大堆和减少栈容量来换取更多的线程的支持能力。