专业的JAVA编程教程与资源

网站首页 > java教程 正文

Java虚拟机栈区域(虚拟机栈描述的是java方法执行的内存模型)

temp10 2024-11-12 13:02:24 java教程 12 ℃ 0 评论

对于每个线程,JVM在创建线程时都会为其创建一个独立的栈空间。Java虚拟机栈的内存不需要是连续的。Java虚拟机仅直接对栈进行两种操作:压栈和弹出帧。每个特定线程的栈也可以称作运行时栈。该线程执行的每个方法调用,包括参数、局部变量、中间计算结果及其他数据,都会存储在对应的运行时栈中。完成一个方法后,相应的栈条目会被移除。当所有方法调用都完成后,栈变空,然后JVM会在线程结束前销毁这个空的栈。栈中存储的数据只能被相应线程访问,对于其他线程来说是不可见的,因此局部变量是线程安全的。栈中的每个条目被称为一个栈帧或激活记录。

栈帧结构

栈帧基本上由三部分构成:本地变量数组操作数栈帧数据。当JVM调用一个Java方法时,首先会检查类数据,确定该方法在本地变量数组和操作数栈中需要的字数(每个单独的方法的本地变量数组和操作数栈的大小以字为单位衡量)。然后,它会为被调用的方法创建一个大小适当的栈帧,并将其压入Java栈。

Java虚拟机栈区域(虚拟机栈描述的是java方法执行的内存模型)

  1. 局部变量数组(LVA)
  • 栈帧中的本地变量部分被组织为从零开始的字数组。
  • 它包含了方法的所有参数和本地变量。
  • 数组中的每个槽或条目是4字节。
  • int、float和reference类型的值占用数组中的1个条目或槽,即4字节。
  • double和long类型的值占用数组中的2个连续条目,即总共8字节。
  • byte、short和char值在存储前会被转换为int类型,并且占用1个槽,即4字节。
  • 但是存储布尔值的方式因JVM而异。不过大多数JVM为布尔值在本地变量数组中分配1个槽。
  • 参数首先按宣布的顺序放入本地变量数组中。

例如:假设有一个名为Example的类,它有一个方法bike(),那么本地变量数组会如下图所示。

// Class Declaration
class Example
{
  public void bike(int i, long l, float f, 
               double d, Object o, byte b)
  {
    
  } 
}
  1. 操作数栈(OS)

JVM利用操作数栈作为工作区,就像使用草稿本一样,主要用来保存中间计算的结果。操作数栈的结构类似于本地变量数组,也是以字为单位排列的。但与通过索引访问本地变量数组不同的是,操作数栈是通过特定的指令来操作的,有的指令负责将数值推入栈中,有的指令负责将数值从栈中弹出,还有的指令执行所需的操作。

比如,当JVM执行下面的代码时,它会计算两个含有int类型数值的本地变量之差,并将结果作为int类型存储到第三个本地变量中:

所以,在这里,前两个指令iload_0和iload_1将会从本地变量数组中推送值到操作数栈中。然后isub指令将会减去这两个值,并把结果存回到操作数栈中。接着在istore_2之后,结果会从操作数栈中弹出,并存储到位置2的本地变量数组中。

  1. 帧数据(FD)

它包含了所有与特定方法相关的符号引用(常量池解析)和普通方法返回信息。

它还包含了对异常表的引用,这个异常表会在发生异常的情况下提供对应的catch块信息。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表