栈内存是描述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. 关于Ubuntu中snap安装软件太慢解决办法

    两种方法,一是下载好包手动安装,二设置snap的代理. 下载安装包方式 到 https://uappexplorer.com/snaps 搜索需要的 snap 包,然后下载 下载的时候选择对应的平台. ...

  2. LeetCode之打家劫舍

    1. 问题 在一条直线上,有n个房屋,每个房屋中有数量不等的财宝,有一个盗 贼希望从房屋中盗取财宝,由于房屋中有报警器,如果同时从相邻的两个房屋中盗取财宝就会触发报警器.问在不触发报警器的前提下,最多 ...

  3. bootstrap select 多选的用法,取值和赋值(取消默认选择第一个的对勾)

    h5自带的select标签可以实现按住ctrl键多选的功能,但是样式及其难看. bootstrap select是很好用的前端插件 ​ 首先引入bootstrap和bootstrap-select的c ...

  4. Zk单机多实例部署

    一.环境准备 当前环境:centos7.3一台软件版本:zookeeper-3.5.2部署目录:/usr/local/zookeeper启动端口:2181,2182,2183配置文件:/usr/loc ...

  5. GO语言测试

    Go语言的测试技术是相对低级的.它依赖一个 go test 测试命令和一组按照约定方式编写的 测试函数,测试命令可以运行这些测试函数.编写相对轻量级的纯测试代码是有效的,而且它很容易延伸到基准测试和示 ...

  6. gitconfig别名配置

    vim ~/.gitconfig 进行配置 [user] name = Your Name email = you@yourdomain.example.com [core] editor = vim ...

  7. docker 访问宿主机网络

    使用宿主机IP 在安装Docker的时候,会在宿主机安装一个虚拟网关docker0,我们可以使用宿主机在docker0上的IP地址来代替localhost. 首先,使用如下命令查询宿主机IP地址: i ...

  8. MYSQL | ERROR 1305(42000) SAVEPOINT *** DOES NOT EXIST

    autocommit模式:在开启情况下,对于每条statement来说,都会自动形成一个commit,也就是会即时对开始和结束一个事务.所以,当出现rollback to savepoint出现这个错 ...

  9. HearthBuddy修改系统时间

    将以下代码保存在.bat文件,然后用管理员权限运行 pushd "%~dp0" #下面修改时间,根据操作系统的语言不同,会有不同的格式,比如2019-10-26date 10/26 ...

  10. 【转】禁用chrome firefox 的 WebRTC功能防止真实IP泄漏

    无论是使用VPN还是其它代理方式,很多时候我们不希望暴露自己的真实IP,且一直以来我们认为VPN是安全的,所有流量都会走VPN. 但最近暴露出一个WebRTC特性,会暴露我们的真实IP.适用浏览器:c ...