学习进入到面向对象初级阶段,看到代码的执行过程便很蒙圈。后来经同学指点告诉我说让我看看面向对象的内存分析,会对代码的理解有所帮助,这里就针对面向对象的内存分析进行阐述。(有些图和代码可能借助于网络和其他博客)
面向对象的内存分析
Java虚拟机的内存可以分为三个区域:栈stack、堆heap、方法区method area。
其中
**栈(stack)**用于存放局部变量名及其值,是方法执行的内存模型。每个方法被调用都会创建一个栈帧。
**堆(heap)**用于存放对象,包括对象的属性和成员方法。
**方法区(method area)**用于存放类的静态变量和字符串常量(data segment),还有相关代码(code segment)
class Computer {
String brand; //品牌
}
public class SxtStu {
// field
int id;
String sname;
int age;
Computer comp;
void study() {
System.out.println("我正在学习!使用我们的电脑,"+comp.brand);
}
SxtStu() {
}
public static void main(String[] args) {
SxtStu stu1 = new SxtStu();
stu1.sname = "张三";
Computer comp1 = new Computer();
comp1.brand = "联想";
stu1.comp = comp1;
stu1.study();
}
}
内存分析图如下
如上所述Java虚拟机的内存可以分为三个区域:栈stack、堆heap、方法区method area。栈(stack)用于存放局部变量名及其值,是方法执行的内存模型。每个方法被调用都会创建一个栈帧。堆(heap)用于存放对象,包括对象的属性和成员方法。方法区(method area)用于存放类的静态变量和字符串常量(data segment),还有相关代码(code segment),在上述代码中,有两个类SxtStu类和 Computer类。
由于main()函数是程序执行的入口,从main()函数开始,程序会在内存栈中开辟一段栈帧,当创建一个对象new SxtStu()时,调用该类的构造方法,在开辟一个构造器的栈帧图中,之后执行构造方法,创建类的对象,当构造器在执行的过程中,会在堆中创建一个对象stu,它里面有属性有方法,即在堆中在分配一段内存块,对象建完之后执行赋值将new SxtStu()赋给stu,stu = new SxtStu(),stu = 7852e922(这是个地址,每次运行不同),即对象stu现在指向7852e922内存块。new Computer()时,同样调用Computer类的构造器,在开辟一个新的栈帧,之后同样会在堆中创建新的对象new Computer();同样有个地址如图,之后把地址赋给c1,使c1指向7852e934内存块,将两者关联起来
简单来说就是每当通过构造函数创建一个类的对象时会相应的在堆中分配一块内存存放该对象的属性和方法。
public static void main(String[] args) {
SxtStu stu1 = new SxtStu();
stu1.sname = "张三";
Computer comp1 = new Computer();
comp1.brand = "联想";
stu1.comp = comp1;
stu1.study();
}
在main()函数中有局部变量stu1和comp1,这两个变量是引用类型变量,存储于栈中。
并且通过构造方法SxtStu()和 Computer()创建了SxtStu类的对象和 Computer类的对象,SxtStu类的对象和Computer类的对象(包括该对象属性和成员方法)存放于堆中,有
//SxtStu类的对象的属性及方法:
int id;//属性
String sname;//属性
int age;//属性
Computer comp;//属性
void study() {//成员方法
System.out.println("我正在学习!使用我们的电脑,"+comp.brand);
}
//Computer类的对象的属性及方法:
String brand; //品牌
方法区(method area)用于存放类的静态变量和字符串常量和类代码。
包括:
SxtStu类代码和 Computer类代码, “张三”; “联想”。
通过对象的引用相应修改对应内存块中的值,
stu1.sname = "张三";
comp1.brand = "联想";
此时sname属性的值变为张三,brand的值变为联想。
需要注意的是当执行完每个方法时依次从栈中删除相应的栈帧
如执行new SxtStu(),SxtStu的构造方法时,删除其栈帧
执行new Computer(),Computer的构造方法时,删除其栈帧
执行完main()方法时,也对应删除其栈帧
这样当执行完整个程序后,栈被释放,这样java虚拟机就会停止,虚拟机停止以后内存就会被释放。
由于还没学习更深层次的比如封装和继承,目前理解先到此。