2019独角兽企业重金招聘Python工程师标准>>>

Java开发中,每当我们在程序中使用new生成一个对象,对象的引用存放在栈里,而对象是存放在堆里的。可以看出栈在Java核心的重要位置。今天我们就继续深入Java核心这个系列,为您介绍Java中的栈、局部变量及其之间的关系。

深入Java核心:Java内存分配原理精讲  探秘Java垃圾回收机制  Java中多态的实现机制

Java中的栈

每当启用一个线程时,JVM就为他分配一个Java栈,栈是以帧为单位保存当前线程的运行状态。某个线程正在执行的方法称为当前方法,当前方法使用的栈帧称为当前帧,当前方法所属的类称为当前类,当前类的常量池称为当前常量池。当线程执行一个方法时,它会跟踪当前常量池。

每当线程调用一个Java方法时,JVM就会在该线程对应的栈中压入一个帧,这个帧自然就成了当前帧。当执行这个方法时,它使用这个帧来存储参数、局部变量、中间运算结果等等。

Java栈上的所有数据都是私有的。任何线程都不能访问另一个线程的栈数据。所以我们不用考虑多线程情况下栈数据访问同步的情况。

像方法区和堆一样,Java栈和帧在内存中也不必是连续的,帧可以分布在连续的栈里,也可以分布在堆里

Java栈的组成元素——栈帧

栈帧由三部分组成:局部变量区、操作数栈、帧数据区。局部变量区和操作数栈的大小要视对应的方法而定,他们是按字长计算的。但调用一个方法时,它从类型信息中得到此方法局部变量区和操作数栈大小,并据此分配栈内存,然后压入Java栈。

局部变量区 局部变量区被组织为以一个字长为单位、从0开始计数的数组,类型为short、byte和char的值在存入数组前要被转换成int值,而long和double在数组中占据连续的两项,在访问局部变量中的long或double时,只需取出连续两项的第一项的索引值即可,如某个long值在局部变量区中占据的索引时3、4项,取值时,指令只需取索引为3的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 = 100;

int b = 98;

int c = a+b;

从图中可以得出:操作数栈其实就是个临时数据存储区域,它是通过入栈和出栈来进行操作的。

帧数据区除了局部变量区和操作数栈外,Java栈帧还需要一些数据来支持常量池解析、正常方法返回以及异常派发机制。这些数据都保存在Java栈帧的帧数据区中。
当JVM执行到需要常量池数据的指令时,它都会通过帧数据区中指向常量池的指针来访问它。

除了处理常量池解析外,帧里的数据还要处理Java方法的正常结束和异常终止。如果是通过return正常结束,则当前栈帧从Java栈中弹出,恢复发起调用的方法的栈。如果方法又返回值,JVM会把返回值压入到发起调用方法的操作数栈。

为了处理Java方法中的异常情况,帧数据区还必须保存一个对此方法异常引用表的引用。当异常抛出时,JVM给catch块中的代码。如果没发现,方法立即终止,然后JVM用帧区数据的信息恢复发起调用的方法的帧。然后再发起调用方法的上下文重新抛出同样的异常。

栈的整个结构

在前面就描述过:栈是由栈帧组成,每当线程调用一个Java方法时,JVM就会在该线程对应的栈中压入一个帧,而帧是由局部变量区、操作数栈和帧数据区组成。那在一个代码块中,栈到底是什么形式呢?下面是我从《深入JVM》中摘抄的一个例子,大家可以看看:

代码片段:

执行过程中的三个快照:

上面所给的图,只想说明两件事情,我们也可用此来理解Java中的栈:

1、只有在调用一个方法时,才为当前栈分配一个帧,然后将该帧压入栈。

2、帧中存储了对应方法的局部数据,方法执行完,对应的帧则从栈中弹出,并把返回结果存储在调用方法的帧的操作数栈中。

转载于:https://my.oschina.net/u/201253/blog/37424

深入Java核心:JVM中的栈和局部变量相关推荐

  1. JVM中的栈和局部变量

    JVM中的栈和局部变量 Java开发中,每当我们在程序中使用new生成一个对象,对象的引用存放在栈里,而对象是存放在堆里的.可以看出栈在Java核心的重要位置.今天我们就继续深入Java核心这个系列, ...

  2. java 栈的变量_深入Java核心:JVM中的栈和局部变量

    操作数栈和局部变量区一样,操作数栈也被组织成一个以字长为单位的数组.但和前者不同的是,它不是通过索引来访问的,而是通过入栈和出栈来访问的.可把操作数栈理解为存储计算时,临时数据的存储区域.下面我们通过 ...

  3. 深入理解JVM中的栈和堆

    深入理解栈 栈又名堆栈,它是一种运算受限的线性表.其限制是仅允许在表的一端进行插入和删除运算.这一端被称为栈顶,相对地,把 另一端称为栈底.其特性是先进后出. 栈是线程私有的,生命周期跟线程相同,当创 ...

  4. Java的JVM运行时栈结构和方法调用详解

    详细介绍了Java 的JVM的运行时栈结构,以及和方法调用详解,包括解析调用和分派调用. JVM对于方法的执行是基于栈的,方法调用--入栈,方法调用完毕--出栈,了解JVM的运行时栈结构,有助于我们更 ...

  5. 【java】JVM中Perm区持续上涨问题

    1.概述 转载:JVM中Perm区持续上涨问题 Java应用Perm区一直呈上涨趋势的原因可以用一个简单的办法排查,就是用btrace去跟踪下是什么地方在调用ClassLoader.defineCla ...

  6. Java - 解释内存中的栈(stack)、堆(heap)和静态区(static area)的用法

    分享一个大牛的人工智能教程.零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击http://www.captainbed.net 通常我们定义一个基本数据类型的变量,一个对象的引用, ...

  7. java 内存区域中的栈

    有人说栈区存放引用,这种说法并不准确. public void Method1() {int i = 4;int y = 2;class1 cls1 = new class1(); } java虚拟机 ...

  8. java基于寄存器_周志明的《深入理解JAVA虚拟机》中基于栈的指令集和基于寄存器的指令集,要好好学习...

    这个知识点是我以前没有的,所以我以前发贴表示完全不理解JAR字节码的执行过程及以本地代码交互的过程. 现在有了这个知识点. 那对JVM的运行机制就了解了大概了. 周志明的<深入理解JAVA虚拟机 ...

  9. 【Java】GoF-23种设计模式在Java核心类库中的应用

    文章目录 Creational patterns(创建型模式) Abstract factory(抽象工厂模式) Builder(建造者模式) Factory method(工厂模式) Prototy ...

最新文章

  1. linux存储--虚拟内存详解MMU、页表(十)
  2. 技术管理:带人和团队管理
  3. selenium之截图
  4. CentOS7 通过wget下载文件到指定目录
  5. 点广告才可以下载的代码
  6. QTable中header高度
  7. layui的table常用方法
  8. 电脑桌面跳出框计算机内存不足,电脑提示虚拟内存不足怎么办 电脑提示虚拟内存不足的原因分析和解决方法...
  9. Android Studio 主题、字体大小的设置
  10. 微信小程序——天气查询
  11. ERNIE-ViL: Knowledge Enhanced Vision-Language Representations Through Scene Graph
  12. On the Factory Floor: ML Engineering for Industrial-Scale Ads Recommendation Models笔记
  13. 服务器部署sas_如何在阿里云SAS上部署WordPress网站
  14. 怎么会这样!超声刀两年后面部塌陷,超声刀失败可以补救吗,让人头大!不要啊
  15. win7计算机左边桌面选项没,win7系统桌面左下角开始菜单不见了的解决方法
  16. GNOME Shell加速演进:BoxPointer, AppMenu和Magnifier
  17. IAR因版本不兼容打不开工程文件解决(Broken options、ICC8051、XLINK)
  18. 拒绝踩坑!源码编译 tensorflow 解决 cuda 不配套 万金油方法
  19. 接入层架构,架构师究竟怎么选型?
  20. 机器学习中四类进化算法的详解(遗传算法、差分进化算法、协同进化算法、分布估计算法)

热门文章

  1. php background-image,css background-image属性怎么用
  2. 上海大学计算机组成原理实验13,上海大学计算机组成原理实验报告11.doc
  3. 计算机桌面上的声音图标没了怎么办,Win7电脑右下角声音图标不见了怎么办?...
  4. 检测网络是否稳定的计算机命令,如何查看自己的网络是否稳定
  5. 萌宠历险记html5游戏在线玩,《神武2》天外魔境现世 萌宠历险记首发
  6. c语言100阶乘的代码,求10000的阶乘(c语言代码实现)
  7. 初识java中数组、数组在内存中、越界异常、空指针异常
  8. python的遍历字典里的键然后放到一个列表里_Python列表和字典互相嵌套怎么办?看完让你没有疑惑...
  9. 32位操作系统,为什么最大支持4G存储空间,2的32次方 = 4294967296bit = 4G,这个怎么计算出来的,
  10. 3、WordCount源码分析