JVM深入理解(3)——运行时数据区(3)

接上篇文章程序计数器继续讲解。

写在最前,本篇文章大部分来源于b站尚硅谷JVM全套教程的提炼,并附带自己的理解。主要是为了帮助自己理解,和用于复习。如果同时还能对其他人有所裨益,那就更好不过了。如果有谬误的地方,还请不吝指出。

背景

由于跨平台的设计,Java指令都是来设计的,不同平台CPU架构不同,所以不能设计为基于寄存器的。

优点:跨平台、指令集小、编译器容易实现
缺点:性能下滑、实现同样功能需要更多指令

栈是运行时的单位,而堆是存储的单位
即:栈解决程序运行的问题,比如程序如何执行,或者如何处理数据等。
而堆解决的是数据存储的问题,比如怎么放,放在哪。(实际上,栈也能存放一些数据,比如:基本类型变量,和对象的引用)

基本内容

java虚拟机栈是什么?
每个线程在创建时都会创建一个虚拟机栈,内部保存栈帧(栈存储数据的基本单位),对应java方法调用。线程私有。

生命周期:与线程一致

作用:主管java程序的运行,保存方法的局部变量、部分结果,并参与方法的调用和返回。

一个栈帧对应一个方法,栈顶方法即是当前方法。

特点:

  • 快速有效,访问速度仅次于程序计数器
  • 操作仅有两个:方法执行,压栈(进栈);执行结束,出栈。
  • 不存在垃圾回收的问题。(但存在OOM问题)

**面试题:**开发中遇到的异常?
内存溢出OOM,StackOverFlow异常等

JVM规范允许java栈的大小是动态的,或者是固定不变的。

如果是固定的,那么每一个线程的java虚拟机栈容量可以在线程创建时独立选定。如果请求分配的栈容量超过允许的最大容量,则会抛出StackOverFlow异常。(允许的容量可能只是内存的一部分)

如果java虚拟机栈可以动态扩展,并且尝试扩展时无法申请到足够内存,或者创建新线程时,没有足够内存创建虚拟机栈,则会抛出OOM异常

通过参数-Xss可以调节线程的最大栈空间,oracle官方查找指令网址

-Xss size
Sets the thread stack size (in bytes). Append the letter k or K to indicate KB, m or M to indicate MB, and g or G to indicate GB.

栈的存储单位

方法和栈帧是一对一的关系:方法执行对应入栈,执行结束对应出栈。
栈帧是一个内存区块,是一个数据集。

一个活动线程中。在一个时间点上,只会出现一个活动的栈帧,即栈顶栈帧,被称为当前栈帧;对应方法:当前方法;定义这个方法的类:当前类

执行引擎运行的所有字节码指令只针对当前栈帧操作。

如果在该方法中调用了其他方法,对应的新栈帧会被创建出来,放在栈的顶端,成为新的当前栈。

栈运行原理

不同线程包含的栈帧不允许存在相互引用,即不可能在一个栈帧之中引用另一个线程的栈帧。

如果当前方法调用了其他方法,方法返回时,当前栈帧会传回此方法的执行结果传给前一个栈帧,接着,JVM丢弃当前栈帧,使得前一个栈帧重新成为当前栈帧。

两种返回函数的方式:return指令;抛出异常。都会导致栈帧被弹出。

栈帧的内部结构

每个栈帧存储:

见下图:
在这里插入图片描述

面试问题

  1. 举例栈溢出的情况(StackOverFlow)
    原因就是栈帧的数量超过了栈被设置的所能容纳的最大容量。
    可以通过-Xss设置栈的大小。如果整个JVM的内存都不够用了,则会出现OOM异常。
  2. 调整栈大小,可以保证不溢出吗? 不能
  3. 分配的栈内存越大越好么? 会挤占其它线程的空间
  4. 方法中定义的局部变量是否线程安全?
    分析:方法内部自身定义的局部变量线程安全(不发布的前提下):每个线程私有虚拟机栈,每个栈帧对应一个方法,里面会生成一个局部变量表,是线程私有的。这个方法不会被其他线程共享,所以如果其他线程也调用这个方法,是在它线程内部的虚拟机栈重新生成的栈帧,和原线程的栈帧除了都拥有指向同一个方法的引用外,没有其它相同点。所以一定是线程安全的。
    如果是方法参数,则不一定是线程安全的。
    如果发布(即将本地变量暴露出此方法之外),则不一定是线程安全的,因为不知道方法的调用者对此对象进行的操作。
    如果变量本身就线程安全(如不可变对象,或线程安全类),或者变量为基本数据类型,则无论是作为方法参数,或是返回值,都是线程安全的。
  5. 垃圾回收会涉及到虚拟机栈么? 不涉及
GCError
程序计数器XX
虚拟机栈X
本地方法栈X
方法区
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值