文档章节

JVM中的Stack和Frame

tantexian
 tantexian
发布于 2016/08/25 11:07
字数 857
阅读 30
收藏 0

JVM执行Java程序时需要装载各种数据,比如类型信息(Class)、类型实例(Instance)、常量数据(Constant)、本地变量等。不同的数据存放在不同的内存区中,这些数据内存区称作“运行时数据区(Runtime Data Area)”。运行时数据区有这样几个重要区:JVM Stack(简称Stack或者虚拟机栈、线程栈、栈等),Frame(又称StackFrame/栈帧、方法栈等),Heap(堆/GC堆,即垃圾收集的对象所在区)。下面简单介绍一下Stack和Frame,对于Heap,请参考垃圾收集相关文章

概览

单个线程内共享的区:PC Register/JVM Stack/Native Method Stack。
所有线程共享的区:Heap/Method Area/Runtime Constant Pool。

上图:运行时数据区。重点是每个线程拥有的PCRegister/Stack以及线程共享的Heap以及常量池(ConstantPool)

 

 

上图:线程栈(VM Statck/Stack)包含的栈帧(Frame)。重点是栈帧和它的结构,操作栈(OperandStack)以及常量池引用。

Stack

结构:{JVM Stack [Frame][Frame][Frame]... }。
JVM Stack在每个线程被创建时被创建,用来存放一组栈帧(StackFrame/Frame)。
JVM Statck的大小可以是固定的,也可以是动态扩展的。如果线程需要一个比固定大小大的Stack,会发生StackOverflowError;如果动态扩展Stack时没有足够的内存或者系统没有足够的内存为新线程创建Stack,发生OutOfMemoryError。

Frame

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

 

局部变量表
局部变量表的大小在编译期就被确定。基元类型数据以及引用和返回地址(returnAddress)占用一个局部变量大小,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)
Frame被创建时,操作栈是空的。操作栈的每个项可以存放JVM的各种类型数据,包括long/double。
操作栈有个栈深,long/double贡献两个栈深。
操作栈调用其它有返回结果的方法时,会把结果push到栈上。

Java代码:

int a=1;
int b=2;
int c=a+b;

对应的指令:

复制代码

0: iconst_1 // push 1到操作栈。大于5的int值会用到 bipush <i> 指令。
1: istore_0 // pop 顶元素,存储到index=0的本地变量。
2: iconst_2 // push 2 到操作栈
3: istore_1 // pop栈顶元素,存储到index=1的本地变量。
4: iload_0  // 把index=0的本地变量加载到栈顶
5: iload_1  // 把index=1的本地变量加载到栈顶
6: iadd     // 把栈顶两个数pop出来相加,并把结果存放到栈顶
7: istore_2 // 结果存储到index=2的本地变量

复制代码

 

Reference

1. http://blog.jamesdbloom.com/JVMInternals.html 

2. http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.5 

3. 《深入理解Java虚拟机》

本文转载自:http://www.cnblogs.com/caca/p/jvm_stack_frame.html

tantexian
粉丝 225
博文 527
码字总数 746616
作品 0
成都
架构师
私信 提问
JVM(Thread/Stack)

JVM Thread/Stack Memory Size JVM Thread/Stack Object states (6 states) JVisualVM

赵-猛
2016/10/12
147
0
java fatal error log

翻译于《Troubleshooting Guide for JavaSE6 with HotSpotVM》 1. 生成位置 -XX:ErrorFile=/fullpath/file,file里可以包含%p表示进程id。如果没声明,默认的名字是hserrpid.log,保存在进程...

yingtju
2018/06/29
0
0
java调用dll出现如下问题,求高手指教!

# # A fatal error has been detected by the Java Runtime Environment: # # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x7795ff4c, pid=7348, tid=4852 # # JRE version: 6.0_21-b06......

xiaomu2013
2014/05/30
506
2
【转】Java Crash原因汇总

如果是Java进程不知道什么原因退出或被杀死,想要分析具体原因,一般来说分下面几步: 1. 拿到Java应用程序的日志文件 2. 查找JVM的致命错误日志 3. 查找操作系统的core dump文件 4. 使用Dtr...

mj4738
2011/12/04
709
0
聊聊java String的intern

序 本文主要研究一下java String的intern String.intern() java.base/java/lang/String.java 当调用intern方法时,如果常量池已经包含一个equals此String对象的字符串,则返回池中的字符串 ...

go4it
04/06
24
0

没有更多内容

加载失败,请刷新页面

加载更多

java通过ServerSocket与Socket实现通信

首先说一下ServerSocket与Socket. 1.ServerSocket ServerSocket是用来监听客户端Socket连接的类,如果没有连接会一直处于等待状态. ServetSocket有三个构造方法: (1) ServerSocket(int port);...

Blueeeeeee
今天
6
0
用 Sphinx 搭建博客时,如何自定义插件?

之前有不少同学看过我的个人博客(http://python-online.cn),也根据我写的教程完成了自己个人站点的搭建。 点此:使用 Python 30分钟 教你快速搭建一个博客 为防有的同学不清楚 Sphinx ,这...

王炳明
昨天
5
0
黑客之道-40本书籍助你快速入门黑客技术免费下载

场景 黑客是一个中文词语,皆源自英文hacker,随着灰鸽子的出现,灰鸽子成为了很多假借黑客名义控制他人电脑的黑客技术,于是出现了“骇客”与"黑客"分家。2012年电影频道节目中心出品的电影...

badaoliumang
昨天
15
0
很遗憾,没有一篇文章能讲清楚线程的生命周期!

(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本。 简介 大家都知道线程是有生命周期,但是彤哥可以认真负责地告诉你网上几乎没有一篇文章讲得是完全正确的。 ...

彤哥读源码
昨天
16
0
jquery--DOM操作基础

本文转载于:专业的前端网站➭jquery--DOM操作基础 元素的访问 元素属性操作 获取:attr(name);$("#my").attr("src"); 设置:attr(name,value);$("#myImg").attr("src","images/1.jpg"); ......

前端老手
昨天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部