JVM中关于虚拟机栈

JVM面试题:
http://www.mianshigee.com/topic/1002ada/

1.栈其实是运行时单位,堆是存储单位。
栈去解决的是运行的问题,而堆是存储单位。
栈是在解决程序的运行问题,程序执行到哪里,数据怎么处理,堆是结局数据放在哪里问题,运行时候数据放在堆里。

每一个线程在创建的时候都会创建java虚拟机栈,栈里面保存你执行的一个个栈帧 对应着一次次的方法调用,也就是虚拟机栈本质也是线程私有的。
局部变量都放在虚拟机栈栈帧里面,当栈结束之后,所有局部变量被回收。

虚拟机栈中有的东西
1.局部变量表
2.操作数栈,就是那个控制栈先进后出结构的栈
⑤. 操作数栈,主要用于保存计算机过程的中间结果,同时作为计算过程中变量临时的存储空间
3.动态连接
4,方法返回地址
当一个栈帧结束之后,程序回到调用方法的地方去,同时别忘记将返回值交回去

栈空间中的异常:
如果线程请求分配栈容量,超过java虚拟机允许最大容量,就会爆出stackOverFlow异常。就是我想要这么大容量,这么高工资,老板大骂你,你个鳖孙!比我工资都高了,撒比,就是stackOverFlowError异常

如果java虚拟机栈不是大小固定的,是可以动态扩展的,并且在尝试扩展中无法申请到足够的内存,那就将抛出来一个outOfMEmoryError异常

设置栈内存空间中的大小:
在这里插入图片描述
在这里插入图片描述
-Xss可以用于设置,虚拟机栈内存的大小,就是你给栈能扩张到多大设置一个固定的值。

不设置虚拟机栈大大小会执行默认值
设置方法:
在这里插入图片描述在这个位置进行设置
比如设置每个线程栈大小位256k
-Xss256k
或者256m
等等

栈到底存储的是什么:
1.栈中数据以栈帧为基础进行存储的。每一个线程中方法都有一个栈帧。
2.在一个线程中,当前时间段只有一个栈帧,称为当前栈帧,当前方法,当前去类
3.新被调用的方法放在栈的最顶层作为当前栈帧。
4.不同线程的栈帧是不可以相互引用的。

java方法中有两种返回指令
1.return
2.Expection,抛出异常但是我们并没有去处理异常
这两种方式都会中断线程,然后弹出线程。

四个方法m1,m2,m3,m4
m1中调用m2,m2调用m3,m3调用m4
m4出现异常抛给m3,m3给m2,m3给m1,m1丢给主方法没有异常处理的话,都没有捕获异常,而是直接层层上交,异常就层层上交,一直交给JVM

栈帧内部结构
在这里插入图片描述
在这里插入图片描述
局部变量表是一个数组,里面基本存储单元是Slot(变量槽),局部变量表里面32位以内类型占用一个slot,64位占用两个

解释了一下为什么静态方法没有this.
在这里插入图片描述稍微理解一下动态连接就行。

在这里插入图片描述3.运行时常量池(runtime constant pool)

当java文件被编译成class文件之后,也就是会生成我上面所说的class常量池,那么运行时常量池又是什么时候产生的呢?

jvm在执行某个类的时候,必须经过加载、连接、初始化,而连接又包括验证、准备、解析三个阶段。而当类加载到内存中后,jvm就会将class常量池中的内容存放到运行时常量池中,由此可知,运行时常量池也是每个类都有一个。在上面我也说了,class常量池中存的是字面量和符号引用,也就是说他们存的并不是对象的实例,而是对象的符号引用值。而经过解析(resolve)之后,也就是把符号引用替换为直接引用,解析的过程会去查询全局字符串池,也就是我们上面所说的StringTable,以保证运行时常量池所引用的字符串与全局字符串池中所引用的是一致的。
在这里插入图片描述
这个和静态链接很接近,是不是,因为在编译期间,就可以却确定,不会发生改变,所以叫非虚方法。不来虚的
在这里插入图片描述非虚方法并不可以被重写,就因为不会被重写,所以是非虚的,因为编译时候啥样运行时候就是什么样子。
比如静态方法就不可以被重写。

关于栈的StackOverflow和outOugmemoryError
当线程请求的栈深度,大于虚拟机所允许的深度的时候,会抛出stackOverflow
说白了,就是一个线程申请的一个栈帧大小太大了。
stackOver说白了,就是一个线程,分配给你的栈空间不够了,给你的东西,你觉得不够用了
java虚拟机栈动态扩展时候,总栈申请不到更多内存时候,就会爆出outOfmemoryError.你已经申请不到东西了。栈空间在整个JVM虚拟机内存空间满了,栈已经申请不到空间了。 没分到手呢,已经没法拿了
1 StackOverflow

每当java程序启动一个新的线程时,java虚拟机会为他分配一个栈,java栈以帧为单位保持线程运行状态;当线程调用一个方法时,jvm压入一个新的栈帧到这个线程的栈中,只要这个方法还没返回,这个栈帧就存在。
如果方法的嵌套调用层次太多(如递归调用),随着java栈中的帧的增多,最终导致这个线程的栈中的所有栈帧的大小的总和大于-Xss设置的值,而产生StackOverflowError溢出异常。
————————————————
2.2 栈内存溢出

java程序启动一个新线程时,没有足够的空间为该线程分配java栈,一个线程java栈的大小由-Xss设置决定;JVM则抛出OutOfMemoryError异常。

1、stackoverflow:

每当java程序启动一个新的线程时,java虚拟机会为他分配一个栈,java栈以帧为单位保持线程运行状态;当线程调用一个方法是,jvm压入一个新的栈帧到这个线程的栈中,只要这个方法还没返回,这个栈帧就存在。
如果方法的嵌套调用层次太多(如递归调用),随着java栈中的帧的增多,最终导致这个线程的栈中的所有栈帧的大小的总和大于-Xss设置的值,而产生生StackOverflowError溢出异常。

2、outofmemory:

2.1、栈内存溢出

java程序启动一个新线程时,没有足够的空间为改线程分配java栈,一个线程java栈的大小由-Xss设置决定;JVM则抛出OutOfMemoryError异常。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值