知识大全 JVM中的栈和局部变量
Posted 变量
篇首语:知识越多越令人陶醉。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 JVM中的栈和局部变量相关的知识,希望对你有一定的参考价值。
深入Java核心:JVM中的栈和局部变量 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
Java开发中 每当我们在程序中使用new生成一个对象 对象的引用存放在栈里 而对象是存放在堆里的 可以看出栈在Java核心的重要位置 今天我们就继续深入Java核心这个系列 为您介绍Java中的栈 局部变量及其之间的关系
Java中的栈
每当启用一个线程时 JVM就为他分配一个Java栈 栈是以帧为单位保存当前线程的运行状态 某个线程正在执行的方法称为当前方法 当前方法使用的栈帧称为当前帧 当前方法所属的类称为当前类 当前类的常量池称为当前常量池 当线程执行一个方法时 它会跟踪当前常量池
每当线程调用一个Java方法时 JVM就会在该线程对应的栈中压入一个帧 这个帧自然就成了当前帧 当执行这个方法时 它使用这个帧来存储参数 局部变量 中间运算结果等等
Java栈上的所有数据都是私有的 任何线程都不能访问另一个线程的栈数据 所以我们不用考虑多线程情况下栈数据访问同步的情况
像方法区和堆一样 Java栈和帧在内存中也不必是连续的 帧可以分布在连续的栈里 也可以分布在堆里
Java栈的组成元素——栈帧
栈帧由三部分组成 局部变量区 操作数栈 帧数据区 局部变量区和操作数栈的大小要视对应的方法而定 他们是按字长计算的 但调用一个方法时 它从类型信息中得到此方法局部变量区和操作数栈大小 并据此分配栈内存 然后压入Java栈
局部变量区 局部变量区被组织为以一个字长为单位 从 开始计数的数组 类型为short byte和char的值在存入数组前要被转换成int值 而long和double在数组中占据连续的两项 在访问局部变量中的long或double时 只需取出连续两项的第一项的索引值即可 如某个long值在局部变量区中占据的索引时 项 取值时 指令只需取索引为 的long值即可
下面就看个例子 好让大家对局部变量区有更深刻的认识 这个图来自《深入JVM》
以下是引用片段 public static int runClassMethod(int i long l float f double d Object o byte b) return ; public int runInstanceMethod(char c double d short s boolean b) return ;
上面代码片的方法参数和局部变量在局部变量区中的存储结构如下图
上面这个图没什么好说的 大家看看就会懂 但是 在这个图里 有一点需要注意
runInstanceMethod的局部变量区第一项是个reference(引用) 它指定的就是对象本身的引用 也就是我们常用的this 但是在runClassMethod方法中 没这个引用 那是因为runClassMethod是个静态方法
操作数栈和局部变量区一样 操作数栈也被组织成一个以字长为单位的数组 但和前者不同的是 它不是通过索引来访问的 而是通过入栈和出栈来访问的 可把操作数栈理解为存储计算时 临时数据的存储区域 下面我们通过一段简短的程序片段外加一幅图片来了解下操作数栈的作用
以下是引用片段 int a = ; int b = ; int c = a+b;
从图中可以得出 操作数栈其实就是个临时数据存储区域 它是通过入栈和出栈来进行操作的
帧数据区除了局部变量区和操作数栈外 Java栈帧还需要一些数据来支持常量池解析 正常方法返回以及异常派发机制 这些数据都保存在Java栈帧的帧数据区中
当JVM执行到需要常量池数据的指令时 它都会通过帧数据区中指向常量池的指针来访问它
除了处理常量池解析外 帧里的数据还要处理Java方法的正常结束和异常终止 如果是通过return正常结束 则当前栈帧从Java栈中弹出 恢复发起调用的方法的栈 如果方法又返回值 JVM会把返回值压入到发起调用方法的操作数栈
为了处理Java方法中的异常情况 帧数据区还必须保存一个对此方法异常引用表的引用 当异常抛出时 JVM给catch块中的代码 如果没发现 方法立即终止 然后JVM用帧区数据的信息恢复发起调用的方法的帧 然后再发起调用方法的上下文重新抛出同样的异常
栈的整个结构
在前面就描述过 栈是由栈帧组成 每当线程调用一个Java方法时 JVM就会在该线程对应的栈中压入一个帧 而帧是由局部变量区 操作数栈和帧数据区组成 那在一个代码块中 栈到底是什么形式呢?下面是我从《深入JVM》中摘抄的一个例子 大家可以看看
代码片段
执行过程中的三个快照
上面所给的图 只想说明两件事情 我们也可用此来理解Java中的栈
只有在调用一个方法时 才为当前栈分配一个帧 然后将该帧压入栈
cha138/Article/program/Java/hx/201311/26394相关参考
知识大全 数据结构考研分类复习真题 第三章 栈和队列[10]
.两个栈共享一片连续内存空间时为提高内存利用率减少溢出机会应把两个栈的栈底分别设在这片内存空间的两端( )【上海海运学院一(分)】 即使对不含相同元素的同一输入
C#教程:隐式类型的局部变量 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 隐式类型的局部变量
浅析VB.NET局部静态变量 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 经过长时间学习VBN
Java多线程开发之线程局部变量的使用 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &
VB.NET循环体内的局部变量 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 我们知道在类或者结
jvm的类加载分三中方式 系统级别rtjar 扩展级别java_home/jre/lib/ext/目录下的jar文件 应用级别环境变量中的classpath或javac  
了解C#特性匿名类型与隐式类型局部变量 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &
知识大全 js 定时器setTimeout无法调用局部变量的解决办法
js定时器setTimeout无法调用局部变量的解决办法 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下
获取运行中的JVM系统属性 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 获取你的JVM系统环境
详细解读JVM中的对象生命周期 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 在JVM运行空间中