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的关系


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


相关文章
|
1天前
|
监控 Java 调度
探秘Java虚拟机(JVM)性能调优:技术要点与实战策略
【6月更文挑战第30天】**探索JVM性能调优:**关注堆内存配置(Xms, Xmx, XX:NewRatio, XX:SurvivorRatio),选择适合的垃圾收集器(如Parallel, CMS, G1),利用jstat, jmap等工具诊断,解决Full GC问题,实战中结合MAT分析内存泄露。调优是平衡内存占用、延迟和吞吐量的艺术,借助VisualVM等工具提升系统在高负载下的稳定性与效率。
12 1
|
5天前
|
Java
JVM打印GC信息
JVM打印GC信息
9 1
|
7天前
|
存储 Java C++
Java虚拟机(JVM)管理内存划分为多个区域:程序计数器记录线程执行位置;虚拟机栈存储线程私有数据
Java虚拟机(JVM)管理内存划分为多个区域:程序计数器记录线程执行位置;虚拟机栈存储线程私有数据,如局部变量和操作数;本地方法栈支持native方法;堆存放所有线程的对象实例,由垃圾回收管理;方法区(在Java 8后变为元空间)存储类信息和常量;运行时常量池是方法区一部分,保存符号引用和常量;直接内存非JVM规范定义,手动管理,通过Buffer类使用。Java 8后,永久代被元空间取代,G1成为默认GC。
18 2
|
3天前
|
存储 监控 算法
深入理解Java虚拟机(JVM)原理与调优技巧
深入理解Java虚拟机(JVM)原理与调优技巧
|
5天前
|
存储 安全 Java
深入理解Java内存模型(JMM)与虚拟机的内存结构(JVM)
深入理解Java内存模型(JMM)与虚拟机的内存结构(JVM)
|
3天前
|
Unix Linux 虚拟化
虚拟机VMware知识积累
虚拟机VMware知识积累
|
2月前
|
算法 虚拟化 C++
VMware虚拟机无法自适应和拖拽复制粘贴和共享目录问题
VMware虚拟机无法自适应和拖拽复制粘贴和共享目录问题
215 0
|
2月前
|
存储 SQL 数据挖掘
服务器数据恢复—误删除VMware虚拟机vmdk文件的数据恢复案例
服务器数据恢复环境: 某大厂PS4000服务器,服务器上部署VMware ESXi虚拟化平台。 服务器故障: 机房断电,重启后服务器中的某台虚拟机不能正常启动。管理员查看虚拟机配置文件,发现无法启动的虚拟机的配置文件除了磁盘文件以外其他配置文件全部丢失,xxx-flat.vmdk磁盘文件和xxx-000001-delta.vmdk快照文件还存在。联系VMware原厂工程师进行诊断,VMware原厂工程师尝试新建一个虚拟机,但发现存储空间不足,于是将故障虚拟机下的xxx-flat.vmdk磁盘文件删除了。VMware工程师重新建了一个虚拟机,分配了固定大小的虚拟磁盘,为虚拟机安装了Window
服务器数据恢复—误删除VMware虚拟机vmdk文件的数据恢复案例
|
12天前
|
存储 IDE 开发工具
【读书笔记】 玩转虚拟机基于Vmware+Windows 虚拟化技术
【读书笔记】 玩转虚拟机基于Vmware+Windows 虚拟化技术
|
13天前
|
虚拟化 UED
vmware-17虚拟机安装教程(保姆级,包含图文讲解,不需注册账户)
vmware-17虚拟机安装教程(保姆级,包含图文讲解,不需注册账户)