面向对象学习笔记5 - Java中方法调用的内存解析
以下是一个简单的Java代码示例,演示对象创建、方法调用及内存存储过程:
// 1. 定义Person类
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void displayInfo() {
System.out.println("Name: " + name + ", Age: " + age);
}
}
// 2. 测试类
public class Main {
public static void main(String[] args) {
// 3. 创建对象
Person person = new Person("Alice", 25);
// 4. 调用对象方法
person.displayInfo();
}
}
内存存储过程解读:
1. 类加载阶段(方法区)
• 当程序启动时:
• Person.class 和 Main.class 被加载到方法区
• 存储类的结构信息(字段、方法、构造函数等)
• 类变量和字节码指令也存储在方法区
2. 对象创建过程(堆内存)
Person person = new Person("Alice", 25);
• new Person() 执行时:
• 在堆内存中分配空间(存储所有实例变量)
• 创建对象头(存储类指针、GC信息等)
• 初始化字段:name=null, age=0
• 执行构造函数进行赋值
内存结构:
堆内存
┌───────────┐
│ Person对象 │
├───────────┤
│ name │ -> 指向字符串常量池中的"Alice"
│ age │ = 25
└───────────┘
3. 引用变量存储(栈内存)
• 局部变量person存储在main方法的栈帧中
• 保存指向堆内存中Person对象的地址指针
内存结构:
栈内存(main方法栈帧)
┌───────────┐
│ person │ -> 堆中Person对象的内存地址
└───────────┘
4. 方法调用过程
person.displayInfo();
• ① 创建新的栈帧(用于displayInfo方法)
• ② 隐式传入this参数(指向调用对象)
• ③ 执行方法字节码(来自方法区)
• ④ 访问堆中的name和age数据
• ⑤ 方法返回后栈帧销毁
内存结构:
栈内存
┌──────────────┐
│ displayInfo │
├──────────────┤
│ this │ -> 指向Person对象
└──────────────┘
↑
┌──────────────┐
│ main方法栈帧 │
└──────────────┘
5. 参数传递(字符串常量池)
• "Alice"字符串存储在字符串常量池(属于方法区)
• 当创建字符串时会复用常量池中的对象
完整生命周期
- 类加载 → 方法区
- 对象实例化 → 堆内存
- 方法调用 → 栈内存
- 引用变量 → 栈内存
- 方法执行 → 方法区字节码 + 栈内存操作
- 垃圾回收 → 当对象不再被引用时,堆内存会被GC回收
关键点总结
• 方法区:类的"蓝图"存储
• 堆内存:对象实际存储位置
• 栈内存:方法调用和局部变量
• 每个方法调用创建独立的栈帧
• this引用隐含传递对象地址
• 对象访问需要通过地址引用跳转

浙公网安备 33010602011771号