堆栈溢出的一些看法

堆栈溢出的一些看法

jvm的内存分配

1.寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制.
2. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放在常量池。)
3. 堆:存放所有new出来的对象,和定义的数组
4. 静态域:存放静态成员(static定义的)
5. 常量池:存放字符串常量和基本类型常量.

~~
String s1 = "china";
String s2 = "china";
String s3 = "china";
String ss1 = new String("china");
String ss2 = new String("china");
String ss3 = new String("china");
~
~

如上图代码我们队 堆,栈,常量池的分类如下
image

堆溢出可以分为以下两种情况(OutOfMemoryError:java heap space):

1、内存泄漏
内存泄漏是指对象实例在新建和使用完毕后,仍然被引用,没能被垃圾回收释放,一直积累,直到没有剩余内存可用

2、内存溢出
内存溢出是指当我们新建一个实力对象时,实例对象所需占用的内存空间大于堆的可用空间。

与栈相关的内存异常有两个():

1、StackOverflowError(方法调用层次太深,内存不够新建栈帧)
,出现此种情况是因为方法运行的时候,请求新建栈帧时,栈所剩空间小于战帧所需空间。线程请求的栈深度大于虚拟机所允许的最大深度
例如,通过递归调用方法,不停的产生栈帧,一直把栈空间堆满,直到抛出异常 :

2、OutOfMemoryError(线程太多,内存不够新建线程)
虚拟机在扩展栈深度时无法申请到足够的内存空间,单线程不好出现,但是一直建线程就会出现

总结

所以我们日常遇见的堆栈溢出,递归一般就是栈溢出,然后对象太大譬如bitmap,或者内存泄露一般都是堆溢出,但是也不绝对,如下面这个方法 虽然是递归但是由于list添加的太大所以直接就堆溢出了.

private static void stack() {
    List list=new ArrayList();
    list.add(new byte[5*1024*1024]);
    stack();
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值