堆:
解决数据存储的问题
数据怎么存放,存放在哪里
栈:
解决程序的运行问题
程序如何执行,如果处理数据
方法区:
解决堆栈信息的产生,是先决条件
辅助堆栈的快永久区Perm
比如
创建一个对象User
User user=new User();
User类的一些信息,类信息、静态信息都存在方法区中
User实例化出来之后,存储到Java堆中,一块内存空间
对象引用
使用的时候,都是使用对象的引用user
user存放在Java栈中,是堆中User对象的一个引用
JVM内存模型简约图
堆区:存放的是使用new关键字创建的类或者数组的(含成员变量);
栈区:存放的是局部变量(注:形参也是局部变量的一中)和对象的声明引用;
方法区(常量池):存放的是字符串常量,其他基本数据类型的常量,类和接口全限定名,属性和方法名,描述符;
静态域:静态变量。
demo1
数据准备
main类
//运行时, jvm 把AppMain的信息都放入方法区
public class AppMain {
//main方法本身放入方法区
public static void main(String[] args) {
Sample test1 = new Sample("测试1");
test1.printName();
}
}
Sample 类
public class Sample {
private String name;
//new Sample实例后,引用放入栈区, 对象放入堆
public Sample(String name){
this.name = name;
}
//printName方法本身放入 方法区
public void printName(){
System.out.println(name);
}
}
在JVM中的栈,堆,方法区的交互
demo2
public class baseTest {
public static void main(String[] args) {
//创建Car类实例,开始通过JVM向内存加载
Car car1 = new Car(4, "red");
car1.show();
Car car2 = new Car(2, "black");
car2.show();
}
}
class Car{
private int wheelNum;//成员变量(堆)
private String color;//成员变量(堆)
public Car() {
}
public Car(int w, String c) {//形参w,c为局部变量(栈)
this.wheelNum = w;
this.color = c;
}
public void show(){//方法名show放到方法区
System.out.println("car:wheelNum-"+wheelNum+"color-"+color);
}
}
当执行代码: Car car1 = new Car(4, “red”);的时候,JVM的内存模型发生的变化是
执行完构造函数时:
在堆中创建对象,对象的属性color 和wheelNum 复制为默认值,而对象的引用0x2332放大的栈区中,当调用构造函数的时候,形参c和w放到栈中,并且给对象的属性复制。执行完构造函数时,形参w和c的生命周期结束,w和c出栈。