虚拟机栈与本地方法栈

什么是栈

栈是一种先进后出(FILO)的数据结构,就像枪的弹夹一样,先压进去的子弹是最后打出来的,一般称之为栈底,而位于“弹夹”最顶端的被称为栈顶

虚拟机栈解释

顾名思义虚拟机栈是JVM中的栈数据结构,此种数据结构是基于线程的,创建了一个线程就相当于创建了一个虚拟机栈,例如我们最熟悉的main方法启动,就启动了一个虚拟机栈。在线程运行的过程中,数据或者引用被加载到栈中,各种数据或者引用会频繁的入栈出栈,等到线程消亡,虚拟机栈也跟着被释放。

虚拟机栈的大小缺省值为1M,可以用JVM参数-Xss调整大小
参考官方文档: https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html
搜索:-Xss

-Xss

可以发现不同平台的缺省值也不同,总的来说,32位的操作系统对应的是320KB,64位的对应的是1024KB

栈帧

Java中每个方法都会创建一个栈帧(Stack Frame),栈帧就是虚拟机栈的子弹,先创建的先被压入栈,然后调用别的方法的时候又压入一个。
例如代码:

public class StackFrameDemo {

    public static void main(String[] args) {
        System.out.println(work());
    }

    public static int work(){
        int a = 1;
        int b = 1;
        int c = a + b;
        return c;
    }

}

运行main方法时
一个main方法启动创建了一个虚拟机栈,此时虚拟机栈中是这样的:


main stackFrame

当我们调用work方法的时候:


work stackFrame

等到work()方法执行完,就出栈,然后main方法出栈,出栈的操作可以看做把子弹射出去,虚拟机栈里就没了。

栈帧详解

栈帧的结构


Stack Frame
栈帧结构

一个栈帧需要分配多少内存,不会受到程序运行时变量数据影响,仅仅取决于虚拟机的实现

局部变量表(Local Variable Table)
  • 在编译代码的时候就可以确定栈帧需要多大的局部表量表,具体的大小可以再编译后的Class文件中看到
  • 局部变量表容量以变量槽(Variable Slot)为最小单位,每个变量槽都可以存储32位长度的内存空间
  • 在方法执行的时候,虚拟机使用局部变量表完成参数值到参数变量表的传递过程,如果执行的是实例方法,那局部表量表的第0个槽位索引默认是用于传递方法所属对象的引用(this关键字)
  • 其余参数则按照参数顺序排列,占用从1开始的局部变量表Slot
  • 基本数据类型以及引用和返回地址(returnAddress)占用一个变量槽,long和double占两个
操作数栈(Operand Stack)
  • 也是在编译期间就可以确定大小
  • 栈帧(Frame)被创建时,操作数栈是空的。操作数栈的每个定都可以存放JVM各种类型的数据,long和double则占两个栈深(和局部变量表是一样的,因为long、double都是64位的数据)
  • 方法执行的过程中,随着各个指令的执行,会有各种数据往操作数栈中写入和读取,也就是出栈和入栈操作
  • 操作数栈调用其他有返回结果的方法时,会把结果push到栈上(通过操作数栈进行参数传递)
动态链接(Dynamic Linking)
  • 动态链接涉及到java的多态特性,动态链接的说明是栈帧内部包含一个指向运行时常量池中该栈帧所属方法的引用,该引用的目的是为了支持动态代理
完成出口(也叫返回地址 Return Address)
  • 方法执行完成的出口,只能由2种方式可以退出:return 返回指令,异常退出
  • 正常退出的流程是,将调用方法的返回值(如果有的话),压入被调用方法的操作数栈顶,被调用的方法根据程序计数器继续执行

通过字节码,查看方法执行时栈帧中的各个数据

  1. 打开类所在的文件夹,通过javac 指令编译java文件为class字节码文件


    javac
  2. 在通过javap -c 查看反汇编字节码,如果有中文用 javac -encoding UTF-8 XXX.java
    work()方法部分的字节码为

  public static int work();
    Code:
       0: iconst_1      加载一个常量1到操作数栈    
       1: istore_0       将一个数值从操作数栈加载到局部变量表0的slot
       2: iconst_1      加载一个常量1到操作数栈
       3: istore_1      将一个数值从操作数栈加载到局部变量表1的slot
       4: iload_0        将局部变量表0位置的数值加载到操作数栈
       5: iload_1        将局部变量表1位置的数值加载到操作数栈
       6: iadd             加法指令
       7: istore_2      将一个数值从操作数栈加载到局部变量表2的slot
       8: iload_2       将局表变量表位置为2的数值加载到操作数栈
       9: ireturn       返回,将操作数栈顶的返回值压入main方法的操作数栈顶

关于字节码指令的解释参考博客:https://cloud.tencent.com/developer/article/1333540

用图形时间轴看起来更加明了


time

这就是work方法执行时,内存中数据的变化。

本地方法栈

与虚拟机栈类似,只不过,虚拟机栈用于管理Java方法的调用。而本地方法栈则用于管理native方法(例如Thread.start0())的调用,由于native方法不是用Java实现的,而是由C语言实现的。事实上虚拟机栈和本地方法栈的区域是非常类似的,在Hotspot中直接把本地方法栈和虚拟机栈合二为一,放在了一个区域之中。当然他们本质上的是两个东西。

参考博客https://www.cnblogs.com/jhxxb/p/11001238.html

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容