JAVA 虚拟机栈

   java 虚拟机栈,在此规定了两种异常情况:

 1.线程请求栈的深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;

 2.如果虚拟机栈可以动态扩展,当扩展是无法申请到足够的内存时会抛出OutOfMemoryError异常.

第一种情况示例分析
 code:
    import  java.util.ArrayList;   
import  java.util.List;   
  
public   class  TailRecursionTest2  {   
    public static void main(String[] args) {   
        TailRecursionTest2 t = new TailRecursionTest2();   
        t.a(0);   
    }
   
  
    public void a(int j) {   
        System.out.println(j);   
        j++;   
        if (j == 10000)   
            return;   
        List list = new ArrayList<Integer>(100000);   
        // 对list进行处理   
        list = null;  //gc友好   
        a(j);   
    }
   
}
 
 分析:
  线程请求栈的深度大于虚拟机所允许的深度,将抛出StackOverflowError异常, 你肯定想到了,是不是重复创建list这个大集合引起的呢?它不  是局部变量吗?怎么也会溢出?是的,list是局部变量,在a的方法栈里引用着,指向heap上的大对象,更关键的问题在于,java是没有尾递归  优化的,递归方法是不会使用同一个栈帧,每一次递归调用,都将压入新的栈帧,并且这个栈帧上又new了一个list变量,引用着heap上新的一  个大集合。随着栈深度的增加, jvm里维持着一条长长的方法调用轨迹以便你能回来,在方法没有返回之前,这些list变量一直被各自的栈帧引  用着,不能被GC,你说,能不OOM吗?

 也许,你想到了个补救方法来挽救程序2,就是每次在处理完list后,我把它设置为null,不让栈帧继续引用着它,咱编写对gc友好的代码,这  不就行了,试试:

 总结:在java里,递归最好咱还是别用,老老实实地while、for;就算递归了,最好递归方法不要new太大的对象,除非你能确定递归的深度不  是那么大,否则OOM和堆栈溢出的阴影将笼罩着你。

第二种情况分析:·[未完。。。]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值