/*栈stack:1.栈描述的是方法执行的内存模型,每个方法被调用时都会创建一个栈帧(储存局部变量、操作数、方法出口等)
* 2.是私有的,不能线程间共享号
* 3.特性:先进后出,后进先出
* 4.是系统自动分配,速度快,是一个连续的空间
* 堆heap:1.用于存储创建好的对象和数组
* 2.只有一个堆。被所有线程共享
* 3.是一个不连续的空间,分配灵活,速度慢
* 方法区method area(静态区):
* 1.只有一个方法区,被所有线程共享
* 2.其实也是堆,只是存储类、常量相关的信息
* 3.存放程序中永远不变或唯一的内容,比如:Class对象、静态变量、字符串常量等
先来一段代码:
public class Student {
//属性
int age;
int id;
String name;
char sex;
Computer comp;
//方法
void study(){
System.out.println("学习"+comp.brand);
}
void run(){
System.out.println("跑步");
}
//构造方法,用于创建这个类的对象,无参的构造方法可由系统自动创建
public Student() {
// TODO Auto-generated constructor stub
}
//程序执行入口,必须要有
public static void main(String[] args) {
Student stu = new Student();
Computer comp = new Computer();
comp.brand = "联想";
stu.comp = comp;
stu.study();
stu.run();
}
}
class Computer{
String brand;
}
我们试着对上面这个代码进行内存分析:
1.javac 编译Student.java这个文件,然后调用虚拟机执行java ,我们就有了内存空间,空间里有栈、堆和方法区,方法区是在堆里面:
2.然后虚拟机调Student这个类,我们找到这个类,把代码加载到空间里,那么在方法区里就有了类的信息:有代码、静态变量、静态方法、字符串常量:"学习" 、 "跑步" 、’ "联想" 这三个。
3.然后找类里的main方法,这个方法是程序执行的入口,必须要有;执行main方法后栈里就会有一个main方法的栈帧,根据代码顺序,main栈帧里会先有一个stu =null,这是一个对象的引用,现在为空,看到new关键字,就是创建一个对象,Student()这个是调用了构造方法,这时栈里面会有个构造器的栈帧,执行完后就创建了一个新的对象,这个对象是放在堆里的,这个对象有属性、方法,目前属性的值都是null或0,这个对象是有一个地址的,“=”这个符号就是把对象地址给了stu,可以把stu打印一下会发现是一个字符串,这样stu就和这个对象关联起来了。Student stu = new Student();这句分析完了。
4.Computer comp = new Computer();这个和上句一样,执行完后,堆里有一个Computer对象,栈里面main方法栈帧里有comp对象引用,两个关联起来了。
5.comp.brand = "联想";这句代码是给属性brand赋值,是把方法区里的字符串常量"联想"指向brand;stu.comp = comp;这个代码是把comp的值给了Student对象comp属性,也就是Student对象comp属性指向Computer对象。
6.stu.study();这句代码执行Student对象的study方法,看这个方法的代码,里面有comp.brand,那我们找comp,comp指向Computer对象,它的brand属性指向"联想",那么就打印出“学习联想”。
这就是代码的全部分析,如果有什么不正确的请指出。