PC寄存器
作用:记住下一条要执行的二进制字节码指令地址(经过解释器翻译成机器码交由CPU运行)
特点:线程私有的;不会存在内存溢出。
- 每个线程拥有一个PC寄存器
- 在线程创建时 创建
- 指向下一条指令的地址
-
方法区
保存装载的类信息
- 类型的常量池
- 字段,方法信息
- 方法字节码
-
堆
通过new关键字,创建对象都会使用堆内存;
特点: 它是线程共享的,堆中对象都需要考虑线程安全问题
- 有垃圾回收机制
- 和程序开发密切相关
- 应用系统对象都保存在Java堆中
- 所有线程共享Java堆
- 对分代GC来说,堆也是分代的
- GC的主要工作区间
栈
作用:限定仅在表头进行插入和删除操作的线性表。即压栈(入栈)和弹栈(出栈)都是对栈顶元素进行操作的。所以栈是后进先出的。
- 线程私有
- 栈由一系列帧组成(因此Java栈也叫做帧栈)
- 帧保存一个方法的局部变量、操作数栈、常量池指针
-
局部变量表
栈帧中,由一个局部变量表存储数据。局部变量表中存储了基本数据类型(boolean、byte、char、short、int、float、long、double)的局部变量(包括参数)、和对象的引用(String、数组、对象等),但是不存储对象的内容。局部变量表所需的内存空间在编译期间完成分配,在方法运行期间不会改变局部变量表的大小。
局部变量的容量以变量槽(Variable Slot)为最小单位,每个变量槽最大存储32位的数据类型。对于64位的数据类型(long、double),JVM 会为其分配两个连续的变量槽来存储。以下简称 Slot 。
JVM 通过索引定位的方式使用局部变量表,索引的范围从0开始至局部变量表中最大的 Slot 数量。普通方法与 static 方法在第 0 个槽位的存储有所不同。非 static 方法的第 0 个槽位存储方法所属对象实例的引用。 ```java public class StackDemo {public static int runStatic(int i,long l,float f,Object o ,byte b){
return 0;
}
public int runInstance(char c,short s,boolean b){
return 0;
}
}
字节码编译<br /><br />可以看到每个方法内的局部变量。
<a name="zCkhb"></a>
## 函数调用组成帧栈
接着,我们使用递归来看
```java
public static int runStatic(int i, long l, float f, Object o, byte b) {
return runStatic(i, l, f, o, b);
}