JVM04_虚拟机栈概述、局部变量表、操作数栈、动态链接、方法的返回地址、附加信息(一)

简介: ①. 什么是Java virtual machine?②. 局部变量表(LocalVariables)

前言:


(栈并不是越大越好,越多可以防止出现StackOverflowError晚点出现,但是栈越大,也就代表着虚拟机栈是一定的,你的栈越大,别的栈就会小)


①. 什么是Java virtual machine?


  • ①. 栈的概述
    每创建一个线程就会创建一个Java栈,每一个Java栈中都会有很多栈帧(局部变量表 | 操作数栈 | 动态链接 | 方法返回地址 | 一些附加信息)


注意:虚拟机栈中不存在GC,但是存在StackOverflowError和OOM


解释:


(1). 虚拟机栈(Java Virtual Machine Stacks)和线程是紧密联系的,每创建一个线程时就会对应创建一个Java栈,所以Java栈也是"线程私有"的内存区域,这个栈中又会对应包含多个栈帧,每调用一个方法时就会往栈中创建并压入一个栈帧,栈帧是用来存储方法数据和部分过程结果的数据结构,每一个方法从调用到最终返回结果的过程,就对应一个栈帧从入栈到出栈的过程[先进后出]


(2). 栈帧中有如下部分组成:


微信图片_20220106133447.png(3). 栈的其他介绍


微信图片_20220106133518.png


  • ②. 存放于栈中的东西如下
    (8种基本类型的变量+对象的引用变量+实例方法都是在函数的栈内存中分配[局部变量])


  • ③. 栈内存溢出(StackOverflowError) -Xss参数


  1. 栈帧过多导致栈内存溢出(方法的递归调用,没设置正确停止条件)


  1. 局部数组过大。当函数内部的数组过大时,有可能导致堆栈溢出


      Exception in thread "main" java.lang.StackOverflowError
    //sayHello()发生了递归
    public class DemoT {
        public static void main(String[] args) {
            sayHello();
        }
        public static void sayHello(){
            sayHello();
        }
    }


④. Java虚拟机规范允许Java栈的大小是动态的或者是固定不变的 掌握


如果采用固定大小的Java虚拟机栈,那每一个线程的Java虚拟机栈容量可以在线程创建的时候独立选定。


如果线程请求分配的栈容量超过Java虚拟机栈允许的最大容量,Java虚拟机将会抛出一个StackoverflowError异常


如果Java虚拟机栈可以动态扩展,并且在尝试扩展的时候无法申请到足够的内存,或者是在创建新的线程时就没有足够的内存区创建对应的虚拟机栈,那Java虚拟机将会抛出一个OutOfMemoryError异常


⑤. 如何设置栈内存的大小? -Xss size (即:-XX:ThreadStackSize)


一般默认为512k-1024k,取决于操作系统(jdk5之前,默认栈大小是256k;jdk5之后,默认栈大小是1024k)


栈的大小直接决定了函数调用的最大可达深度


平台 jdk8
linux 1024
MacOS 1024
window 0


⑥. 栈和堆的区别是什么?


从GC、OOM、StackOverflowError的角度。


(栈中不存在GC,当固定大小的栈会发生StackOverflowError,动态的会发生OOM。堆中GC、OOM、StackOverflowError都存在)


从堆栈的执行效率


(栈的效率高于堆)


内存大小,数据结构


(堆的空间比栈的大一般,栈是一种FIFO先进后出的模型。堆中结构复杂,可以有链表、数组等)


栈管运行,堆管存储


②. 局部变量表(LocalVariables)


①. 定义为一个数字数组,主要用于存储方法参数和定义在方法体内的局部变量(这些数据类型包括各种基本数据类型、对象引用(reference)以及return Address类型)


②. 由于局部变量是建立在线程的栈上,是线程私有数据,因此不存在数据安全问题


③. 局部变量表所需容量大小是在编译期确定下来的。(并保存在方法Code属性的maximum local variables数据项中,在方法运行期间不会改变局部变量表的大小的)


//使用javap -v 类.class 或者使用jclasslib
public class LocalVariableTest {
    public static void main(String[] args) {
        LocalVariableTest test=new LocalVariableTest();
        int num=10;
        test.test1();
    }
    public static void test1(){
        Date date=new Date();
        String name="xiaozhi";
    }
}


jclasslib说明:


微信图片_20220106133738.png微信图片_20220106133742.png


image.png


④. 关于slot的理解(引用数据类型(方法的返回地址)占用1个slot)


局部变量表,是基本的存储单元是slot(变量槽)


在局部变量表中,32位以内的类型只占有一个slot(包括引用数据类型),64位的类型(long和double)占有两个slot


byte、short、char在存储前被转换为int,boolean也被转换为int(0表示fasle,非0表示true)。long和double则占据两个slot


  • ⑤. Jvm会为局部变量表中的每一个slot都分配一个访问索引,通过这个索引即可成功访问到局部变量表中指定的局部变量值


  • ⑥. 如果需要访问局部变量表中一个64bit的局部变量值时,只需要使用前一个索引即可(比如:访问long或double类型变量)


微信图片_20220106133842.png


⑦. 如果当前帧是由构造方法或者实例方法创建,那么该对象引用this将会放在index为0的slot处


微信图片_20220106133900.png


⑧. 栈帧中的局部变量表中的槽位是可以复用的,如果一个局部变量过了其作用域,那么在其作用域之后申请的新的局部变量就很可能会复用过期局部变量的槽位,从而节省资源的目的


  public void localVar2(){
    {
      int a=0;
      System.out.println(a);
    }
    //此时的b就会复用a的槽位
    int b=0;
  }


⑨. 与GC Roots的关系


局部变量表中的变量也是重要的垃圾回收根节点,只要被局部变量表中直接或间接引用的对象都不会被回收


相关文章
|
24天前
|
监控 算法 Java
Java虚拟机(JVM)的垃圾回收机制深度解析####
本文深入探讨了Java虚拟机(JVM)的垃圾回收机制,旨在揭示其背后的工作原理与优化策略。我们将从垃圾回收的基本概念入手,逐步剖析标记-清除、复制算法、标记-整理等主流垃圾回收算法的原理与实现细节。通过对比不同算法的优缺点及适用场景,为开发者提供优化Java应用性能与内存管理的实践指南。 ####
|
15天前
|
监控 算法 Java
Java虚拟机(JVM)垃圾回收机制深度剖析与优化策略####
本文作为一篇技术性文章,深入探讨了Java虚拟机(JVM)中垃圾回收的工作原理,详细分析了标记-清除、复制算法、标记-压缩及分代收集等主流垃圾回收算法的特点和适用场景。通过实际案例,展示了不同GC(Garbage Collector)算法在应用中的表现差异,并针对大型应用提出了一系列优化策略,包括选择合适的GC算法、调整堆内存大小、并行与并发GC调优等,旨在帮助开发者更好地理解和优化Java应用的性能。 ####
24 0
|
5天前
|
存储 Java 开发者
浅析JVM方法解析、创建和链接
上一篇文章《你知道Java类是如何被加载的吗?》分析了HotSpot是如何加载Java类的,本文再来分析下Hotspot又是如何解析、创建和链接类方法的。
|
12天前
|
存储 监控 算法
深入探索Java虚拟机(JVM)的内存管理机制
本文旨在为读者提供对Java虚拟机(JVM)内存管理机制的深入理解。通过详细解析JVM的内存结构、垃圾回收算法以及性能优化策略,本文不仅揭示了Java程序高效运行背后的原理,还为开发者提供了优化应用程序性能的实用技巧。不同于常规摘要仅概述文章大意,本文摘要将简要介绍JVM内存管理的关键点,为读者提供一个清晰的学习路线图。
|
15天前
|
存储 监控 算法
Java虚拟机(JVM)垃圾回收机制深度解析与优化策略####
本文旨在深入探讨Java虚拟机(JVM)的垃圾回收机制,揭示其工作原理、常见算法及参数调优方法。通过剖析垃圾回收的生命周期、内存区域划分以及GC日志分析,为开发者提供一套实用的JVM垃圾回收优化指南,助力提升Java应用的性能与稳定性。 ####
|
18天前
|
机器学习/深度学习 监控 算法
Java虚拟机(JVM)的垃圾回收机制深度剖析####
本文深入探讨Java虚拟机(JVM)的垃圾回收机制,揭示其工作原理、常见算法、性能调优策略及未来趋势。通过实例解析,为开发者提供优化Java应用性能的思路与方法。 ####
31 1
|
23天前
|
监控 Java Spring
JVM如何监控某个方法的入参和相应结果?
JVM如何监控某个方法的入参和相应结果?
33 0
|
25天前
|
监控 算法 Java
深入理解Java虚拟机(JVM)的垃圾回收机制
【10月更文挑战第21天】 本文将带你深入了解Java虚拟机(JVM)的垃圾回收机制,包括它的工作原理、常见的垃圾收集算法以及如何优化JVM垃圾回收性能。通过本文,你将对JVM垃圾回收有一个全新的认识,并学会如何在实际开发中进行有效的调优。
41 0
|
28天前
|
Ubuntu 网络安全 虚拟化
VMware虚拟机ping不通原因排查及分析
下面以 VMware 虚拟机为例进行介绍。
402 3
|
1月前
|
存储 SQL 数据库
虚拟化数据恢复—Vmware虚拟机误还原快照的数据恢复案例
虚拟化数据恢复环境: 一台虚拟机从物理机迁移到ESXI虚拟化平台,迁移完成后做了一个快照。虚拟机上运行了一个SQL Server数据库,记录了数年的数据。 ESXI虚拟化平台上有数十台虚拟机,EXSI虚拟化平台连接了一台EVA存储,所有的虚拟机都存放在EVA存储上。 虚拟化故障: 工组人员误操作将数年前迁移完成后做的快照还原了,也就意味着虚拟机状态还原到数年前,近几年数据都被删除了。 还原快照相当于删除数据,意味着部分存储空间会被释放。为了不让这部分释放的空间被重用,需要将连接到这台存储的所有虚拟机都关掉,需要将不能长时间宕机的虚拟机迁移到别的EXSI虚拟化平台上。
106 50