JVM运行时数据区
JVM在运行过程中会把它所管理的内存划分成若干不同的数据区域。
- 线程私有:程序计数器、虚拟机栈、本地方法栈 (
主要存放指令
) - 线程共享:堆、方法区 (
主要存放数据
)
一、程序计数器
程序计数器是用于存放下一条指令所在单元的地址的地方。
我们可以随意拿一个class
文件进行反编译,看看其结构。
如下,JvmDemo.class
文件:
cafe babe 0000 0033 0045 0a00 1000 2608
0027 0900 0f00 2808 0029 0900 0f00 2a0a
002b 002c 0900 2d00 2e07 002f 0a00 0800
260a 0008 0030 0a00 0800 310a 0032 0033
...
TIP
: javap
是 Java class文件分解器,可以反编译(即对javac编译的文件进行反编译),也可以查看java编译器生成的字节码。用于分解class文件。
执行javap -v ./JvmDemo.class > JvmDemo.txt
,将JvmDemo.class
文件分解为JvmDemo.txt
:
其左侧的序号就是所谓的程序计数器
,用于确定代码的执行顺序。
二、虚拟机栈
存储当前线程
运行方法所需的数据、指令、返回地址。
1、虚拟机栈
栈
这个数据结构的特性就是先进后出
。虚拟机栈主要存放的是栈帧
。
2、栈帧
类中每一个方法对应一个栈帧。通俗的说,可以将程序调用的一个方法看做一个栈帧
。
栈帧可以划分为四个结构:
- 局部变量表
- 操作数栈
- 动态连接
- 返回地址
3、虚拟机栈的StackOverflowError
当线程调用一个方法,就会产生一个栈帧
,存储在栈中。若是方法的内部还有方法调用的话,那就会有新的栈帧
存放在栈中,成为栈顶元素
。
如线程对下面方法的调用:
public void A(){
B();
...其他操作
}
public void B(