Java Runtime Data Area & 函数调用栈 JVM Stack & 栈帧 Stack Frame

更多 Java 虚拟机方面的文章,请参见文集《Java 虚拟机》


运行时数据区 Runtime Data Area

JVM 执行 Java 程序时需要装载各种数据,比如类型信息(Class)、类型实例(Instance)、常量数据(Constant)、本地变量等。
不同的数据存放在不同的内存区中,这些数据内存区称作运行时数据区(Runtime Data Area)

运行时数据区有这样几个重要区:

  • JVM Stack(简称 Stack 或者虚拟机栈、线程栈、栈等)
  • Frame(又称StackFrame/栈帧、方法栈等)
  • Heap(堆/GC堆,即垃圾收集的对象所在区)

单个线程内共享的区:

  • PC Register 寄存器
  • JVM Stack 虚拟机栈
  • Native Method Stack 本地方法栈

所有线程共享的区:

  • Heap 堆
  • Method Area 方法区,其中包含 Runtime Constant Pool 常量池
运行时数据区 Runtime Data Area

函数调用栈 JVM Stack

结构:
{JVM Stack [Frame][Frame][Frame]... }

Java 的函数调用栈就是 Java 虚拟机栈,它是线程私有的,与线程一同被创建,用于存储栈帧 Stack Frame,如下图所示。

线程栈(VM Statck/Stack)包含的栈帧(Frame)

ThrowablegetStackTrace() 可以返回当前线程的虚拟机栈信息,返回数组的第一个元素是栈顶元素,最后一个元素是栈底元素

示例代码如下:

public class StackTrace_Test {
    public void function1() {
        function2();
    }

    public void function2() {
        function3();
    }

    public void function3() {
        Throwable ex = new Throwable();

        StackTraceElement[] stackElements = ex.getStackTrace();

        System.out.println("Stack Length: " + stackElements.length);

        for (StackTraceElement stackTraceElement : stackElements) {
            System.out.println("Method Name: "
                    + stackTraceElement.getMethodName() + " Line Number: "
                    + stackTraceElement.getLineNumber());
        }
    }

    public static void main(String[] args) {
        StackTrace_Test t = new StackTrace_Test();
        t.function1();
    }
}

输出如下:

Stack Length: 4
Method Name: function3 Line Number: 11
Method Name: function2 Line Number: 7
Method Name: function1 Line Number: 3
Method Name: main Line Number: 26

栈帧 Stack Frame

结构:
{Frame [ReturnValue] [LocalVariables[ ][ ][ ][ ]...] [OperandStack [ ][ ][ ]...] [ConstPoolRef] }

每次方法调用均会创建一个对应的 Frame,方法执行完毕或者异常终止,Frame 被销毁。
一个方法 A 调用另一个方法 B 时,A 的 Frame 停止,新的 Frame 被创建赋予 B,执行完毕后,把计算结果传递给 A,A 继续执行。

局部变量表 LocalVariables

局部变量表的大小在编译期就被确定,这些值并放在class文件中。

局部变量区被组织成一个以字长为单位、从 0 开始计数的数组

字节码指令通过以 0 开始的索引来使用其中的数据。

  • 类型为 int、float、refence(引用)和returnAdress(方法出口)的值在数组内只占据一项
  • 类型为 byte、short、char 的值在存入数组时都先转换为 int 值,因此同样只占据一项
  • 类型为 long 和 double 的值在数组中却占据了连续两项。

局部变量区包含了对应的 方法参数 和 局部变量!!!

Java代码 int a=0; int b=1; int c=2; 对应的局部变量表如下:

LocalVariableTable:
Start Length Slot Name Signature
2 12 0 a I
4 10 1 b I
6 8 2 c I

其中:

  • Start 变量偏移量。
  • Length 作用域范围长度。[ Start, Start + Length )就是该变量的作用域。
  • Slot 一个Slot能存储 32bit 的数据类型、引用、返回地址,long / dobule需要两个Slot。

操作数栈 OperandStack

操作数栈 OperandStack 的大小在编译期就被确定,这些值并放在class文件中。

Frame 被创建时,操作栈是空的。操作栈的每个项可以存放 JVM 的各种类型数据,包括 long / double。
操作栈有个栈深,long / double贡献两个栈深。
操作栈调用其它有返回结果的方法时,会把结果 push 到栈上。

当虚拟机调用一个方法时,它从对应的类的类型信息得到 局部变量表 LocalVariables 和 操作数栈 OperandStack 的大小,并据此分配栈帧内存,并压入 JVM Stack 中。


引用:
JVM中的Stack和Frame

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

推荐阅读更多精彩内容