两个对象内存图
相关代码:
内存示意图:
首先知道有三个内存空间,分别是堆内存、栈内存、方法区。
1.首先含有main方法的类的字节码文件加载入方法区
2.调用main主方法,进入栈内存
3.声明Student类定义的s1变量进入栈内存
此时要将Student类的字节码文件加载入方法区,成员方法、成员变量也随之加载进入
4.new Student(); 创建Student类的实例对象,在堆内存中开辟空间产生地址。并将根据方法区的Student类字节码文件将成员变量加载入堆内存。(成员变量的初始值为默认值)
成员方法不进入堆内存,只是其地址加载入堆内存
5.new完成后,栈内存变量s1接收到堆内存中开辟的地址
6.打印s1的地址。
7.给成员变量s1.name、s1.age赋值。对象s1根据地址找到堆内存,给成员变量重新赋值
9.再次打印成员变量s1.mane和s1.age。对象s1根据地址找到堆内存,输出成员变量的值
10.之后s1.read();调用成员方法,对象s1根据地址找到堆内存,再根据成员方法的地址找到方法区中字节码文件调用read方法
11.将s1.read方法加载到栈内存中去运行,打印内容
12.s1.read()调用方法打印完后退出栈
13.又声明了Student类型的变量s2进入栈内存
这里.class字节码文件不需要再次加载,因为前面声明s1时已经将Student类的字节码文件加载入方法区
14.new Student(); 创建Student类的实例对象,在堆内存中再开辟一块空间,根据方法区的Student类字节码文件将成员变量加载入堆内存并初始化。成员方法的地址进入堆内存。
15.将开辟的空间地址传给栈内存变量s2。
16.打印s2的地址。
17.给成员变量s2.name、s2.age赋值。对象s2根据地址找到堆内存,给成员变量重新赋值
18.再次打印成员变量s2.mane和s2.age。对象s2根据地址找到堆内存,输出成员变量的值
19.之后s2.read();调用成员方法,对象s2根据地址找到堆内存,再根据成员方法的地址找到方法区中字节码文件中的read方法
20.将s2.read方法加载到栈内存中去运行,打印内容
21.s2.read()调用方法打印完后退出栈
22.最后main方法也退出栈
运行截图: