Java程序在运行前都要为程序开辟空间,JVM(java虚拟机)内存的划分分为5个部分:
- 寄存器
- 本地方法区
- 方法区
- 栈内存
- 堆内存
栈内存
一种运算受限的线性表。限定只能在表尾进行插入和删除操作的线性表。用于存储局部变量(栈的生命周期短是因为变量都有自己的作用域,一旦离开作用域,变量就会被释放,也因此栈内存的更新速度很快)
堆内存
存储数组和new出来的对象。堆中的内存不会像栈中的数据被随时释放,在堆中已经废弃的对象只有等待垃圾回收器回收。(如果堆内存中的对象没有被任何引用变量指向,就表明该对象是废弃的)
接下来用一个例子看变量和对象在堆和栈中的存储情况
public class Stack {
public static void main(String[] args) {
String name = "清杉夫人";
int age = 21;
Stack stack = new Stack();
stack.print(name,age);
}
public void print(String name,int age) {
int a=0;
System.out.println(name+"..."+age);
}
}
过程
- 主方法加载进方法区
- 变量加载进栈的主方法中
- stack对象的引用变量加载进栈中
- Stack对象加载进堆中
- print方法加载进栈中
- 方法中的参数是传递的,所以参数也加载进栈中
- a加载进栈中的print方法中
每每创建一个对象,这个对象就会加载进堆内存中,栈内存中存储的并不是引用变量本身,而是堆内存中变量以及对象的地址,这就很像c语言中的指针,不过java堆这种指针进行了封装。java程序不允许直接访问堆内存中的对象,只能通过堆内存中的引用来操作该对象。