栈内存是描述java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、返回出口等信息。每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。栈帧(Frame)是用来存储数据和部分过程结果的数据结构,同时也被用来处理动态链接(Dynamic Linking)、方法返回值和异常分派(Dispatch Exception)。栈帧随着方法调用而创建,随着方法结束而销毁——无论方法是正常完成还是异常完成(抛出了在方法内未被捕获的异常)都算作方法结束。

1. JVM栈内存结构

1.1 局部变量表

局部变量表(Local Variables Table)也可以称之为本地变量表,它包含在一个独立的栈帧中。顾名思义,局部变量表主要用于存储方法参数和定义在方法体内的局部变量,这些数据类型包括各类原始数据类型、对象引用(reference),以及returnAddress类型。局部变量表所需的容量大小在编译期就可以被完全确定下来,并保存在方法的Code属性中。大家思考一下,既然方法体内定义的局部变量是存储在栈帧中的局部变量表里的,那么原始数据类型的成员变量的值是否也存储在局部变量表中呢?其实如果是定义在方法体外的成员变量,不止是作用域发生了变化,更重要的是,其值也并非还是存储在局部变量表里,而是存储在对象内存空间的实例数据中,整体来看即存储在Java堆区内。简单来说,与线程上下文相关的数据存储在Java栈中,反之则存储在Java堆区内。

1.2. 操作数栈

每一个独立的栈帧中除了包含局部变量表以外,还包含一个后进先出(Last-In-First-Out)的操作数栈,也可以称之为表达式栈(Expression Stack)。操作数栈和局部变量表在访问方式上存在着较大差异,操作数栈并非采用访问索引的方式来进行数据访问的,而是通过标准的入栈和出栈操作来完成一次数据访问。每一个操作数栈都会拥有一个明确的栈深度用于存储数值,一个32bit的数值可以用一个单位的栈深度来存储,而2个单位的栈深度则可以保存一个64bit的数值,当然操作数栈所需的容量大小在编译期就可以被完全确定下来,并保存在方法的Code属性中。

1.3. 动态链接

每一个栈帧内部除了包含局部变量表和操作数栈之外,还包含一个指向运行时常量池中该栈帧所属方法的引用,包含这个引用的目的就是为了支持当前方法的代码能够实现动态链接(Dynamic Linking)。在运行时常量池,一个有效的字节码文件中除了包含类的版本信息、字段、方法以及接口等描述信息外,还包含一项信息,那就是常量池表(Constant Pool Table),那么运行时常量池就是字节码文件中常量池表的运行时表示形式。在一个字节码文件中,描述一个方法调用了另外的其他方法时,就是通过常量池中指向方法的符号引用(Symbolic Reference)来表示的,那么动态链接的作用就是为了将这些符号引用转换为调用方法的直接引用。

1.4. 方法返回值

一个方法在执行的过程中将会产生两种调用结果:一种是方法正常调用完成,而另外一种则是方法异常调用完成。如果是方法正常调用完成,那么这就意味着,被调用的当前方法在执行的过程中将不会有任何的异常被抛出,并且方法在执行的过程中一旦遇见字节码返回指令时,将会把方法的返回值返回给它的调用者,不过一个方法在正常调用完成之后究竟需要使用哪一个返回指令还需要根据方法返回值的实际数据类型而定。在字节码指令中,返回指令包含ireturn(当返回值是boolean、byte、char、short和int类型时使用)、lreturn、freturn、dreturn以及areturn,另外还有一个return指令供声明为void的方法、实例初始化方法、类和接口的初始化方法使用。

2. 栈上分配

jvm里面new Object对象除了在堆内存创建外,也可以在栈上创建,我们类里面的方法对应一个个的栈帧,方法里面new出来的对象,是局部不共享的。当然我们栈帧里面创建的对象如果太大,也会直接在堆空间分配。

3. 内存逃逸

当我们栈帧里面new出来的对象,如果被外部引用后,此时该对现象不会被分配在栈帧内而是直接分配在堆区间

JVM(二) 栈内存结构的更多相关文章

  1. JVM学习之 内存结构

    目录 一.引言 1.什么是JVM? 2.学习JVM有什么用 3.常见的JVM 4.学习路线 二.内存结构 1. 程序计数器 1.1 定义 1.2作用 2. 虚拟机栈 2.1定义 2.2栈内存溢出 2. ...

  2. JVM原理及内存结构

    JVM是按照运行时数据的存储结构来划分内存结构的,JVM在运行java程序时,将它们划分成几种不同格式的数据,分别存储在不同的区域,这些数据统一称为运行时数据.运行时数据包括java程序本身的数据信息 ...

  3. jvm(1):内存结构

    JVM内存结构 JVM内存的运行时数据区: 线程私有(在线程启动时创建) 程序计数器Program Counter Register 一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器, ...

  4. JVM之--Java内存结构(第一篇)

    最近在和同事朋友聊天的时候,发现一个很让人思考的问题,很多人总觉得JVM将java和操作系统隔离开来,导致很多人不用熟悉操作系统,甚至不用了解JVM本身即可完全掌握Java这一门技术,其实个人的观点是 ...

  5. JVM宏观认知&&内存结构

    JVM宏观认知 1.什么是虚拟机? 虚拟机是一种软件. 可分为系统虚拟机(仿真物理机)和程序虚拟机(执行单个计算机程序,比如JVM). 2.什么是Java虚拟机(JVM)? JVM是一种将字节码转化为 ...

  6. JVM运行时内存结构学习

    学习JVM运行模型比较重要,先看一幅图片: 运行时数据区(内存结构) :  1.方法区(Method Area)类的所有字段和方法字节码,以及一些特殊方法如构造函数,接口代码也在这里定义.简单来说,所 ...

  7. 【JVM】JVM 概述、内存结构、溢出、调优(基础结构+StringTable+Unsafe+ByteBuffer)

    什么是 JVM ? 定义 Java Virtual Machine - java 程序的运行环境(java 二进制字节码的运行环境) 好处 一次编写,到处运行 自动内存管理,垃圾回收功能 数组下标越界 ...

  8. JVM 运行时内存结构

      1.JVM内存模型       JVM运行时内存=共享内存区+线程内存区 1).共享内存区       共享内存区=持久带+堆       持久带=方法区+其他       堆=Old Space ...

  9. JVM运行时内存结构

    原文转载自:http://my.oschina.net/sunchp/blog/369707 1.JVM内存模型 JVM运行时内存=共享内存区+线程内存区 1).共享内存区 共享内存区=持久带+堆 持 ...

随机推荐

  1. Mujin Programming Challenge 2017题解

    传送门 \(A\) 似乎并不难啊然而还是没想出来-- 首先我们发现对于一个数\(k\),它能第一个走到当且仅当对于每一个\(i<k\)满足\(x_i\geq 2i-1\),这样我们就可以把所有的 ...

  2. python2 && python3 的 input函数

    Python2.x中的input()函数input()函数让我们明确我们输入的是数字格式还是字符格式,就是我们自己要知道我们想要的是什么,数字格式直接输入,字符格式必须加上单引号或者双引号,以确定我们 ...

  3. docker 随笔记录

    .docker 固定网络ip地址,启动 Docker的时候,用 --network 参数,可以指定网络类型 eg:docker run -itd --name test1 --network brid ...

  4. 任意模数FFT

    任意模数FFT 这是一个神奇的魔法,但是和往常一样,在这之前,先 \(\texttt{orz}\ \color{orange}{\texttt{matthew99}}\) 问题描述 给定 2 个多项式 ...

  5. Spring boot 事务Transactional

    开启事务只需要加上注解@Transactional即可 // 默认情况下数据库的事务作用范围是在JapRepository 的crud上 // save 一旦执行成功,就会进行提交 // 开启事务后遇 ...

  6. 在Ubuntu 18.04 下安装mysql,没有初始密码,重设root密码

    在Ubuntu 18.04 下安装mysql 不知道是由于mysql更新为新版还是.Ubuntu18.04中的特性,安装过程中没有设置密码的环节,在网络上找了半天,总算解决了!特此记录下来,以便以后查 ...

  7. C# 复制数组容易踩到的坑--引用类型与值类型

    原文链接:https://my.oschina.net/u/3744313/blog/1794235 笔者近期做的项目里大量使用了数组,而在使用过程中,笔者曾经遇到了一个比较低级的问题:如何将一个数组 ...

  8. 给Oracle字段和表加注释

    给字段加注释 comment on column testtb17.AGE is '年龄';comment on column testtb17.CREATEDTIME is '创建时间';comme ...

  9. 用java输出杨辉三角

    杨辉三角:它的两个边都是1,内部其它都是肩上两个数的和 第一种: package aaa; public class YangHui { public static void main(String[ ...

  10. TextView: android:ellipsize="marquee" 跑马灯效果无效的问题

    今天练习的时候想实现一个文字的跑马灯效果,本来想自己手动实现的,不过突然想起来android里的TextView属性似乎自带了这个效果,叫: android:ellipsize ,平时都是把它的属性值 ...