Java内存分配案例
目录介绍
- 01.首先看代码案例
- 02.JVM加载类过程
- 03.对构造方法赋值
- 04.通过对象调用方法
01.首先看代码案例
以下面代码为例,来分析,Java 的实例对象在内存中的空间分配。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40//JVM 启动时将 Person.class 放入方法区
public class Person {
//静态变量,直接放到常量池中
public static final String number = "13667225184";
//new Person 创建实例后,name 引用放入堆区,name 对象放入常量池
private String name;
//new Person 创建实例后,age = 0 放入堆区
private int age;
//Person 方法放入方法区,方法内代码作为 Code 属性放入方法区
public Person(String name, int age) {
this.name = name;
this.age = age;
}
//toString 方法放入方法区,方法内代码作为 Code 属性放入方法区
@Override
public String toString() {
return "Person{" + "name='" + name + '\'' + ", age=" + age + '}';
}
}
//JVM 启动时将 Test.class 放入方法区
public class Test {
//main 方法放入方法区,方法内代码作为 Code 属性放入方法区
public static void main(String[] args) {
//person1 是引用放入虚拟机栈区,new 关键字开辟堆内存 Person 自定义对象放入堆区
Person person1 = new Person("张三", 18);
Person person2 = new Person("李四", 20);
//通过 person 引用创建 toString() 方法栈帧
person1.toString();
person2.toString();
}
}
02.JVM加载类过程
- 首先 JVM 会将 Test.class, Person.class 加载到方法区,找到有 main() 方法的类开始执行。
- 分析步骤
- 如上图所示,JVM 找到 main() 方法入口,创建 main() 方法的栈帧放入虚拟机栈,开始执行 main() 方法。
- Person person1 = new Person(“张三”, 18);
- 执行到这句代码时,JVM 会先创建 Person。实例放入堆区,person2 也同理。
03.对构造方法赋值
创建完 Person 两个实例,main() 方法中的 person1,person2 会指向堆区中的 0x001,0x002(这里的内存地址仅作为示范)。紧接着会调用 Person 的构造函数进行赋值,如下图:
如上图所示,新创建的的 Person 实例中的 name, age 开始都是默认值。 调用构造函数之后进行赋值,name 是 String 引用类型,会在常量池中创建并将地址赋值给 name,age 是基本数据类型将直接保存数值。
注:Java 中基本类型的包装类的大部分都实现了常量池技术,这些类是 Byte, Short, Integer, Long, Character, Boolean,另外两种浮点数类型的包装类则没有实现。
基本数据类型 包装类(是否实现了常量池技术) byte Byte 是 boolean Boolean 是 short Short 是 char Character 是 int Integer 是 long Long 是 float Float 否 double Double 否
04.通过对象调用方法
- Person 实例初始化完后,执行到 toString() 方法,同 main() 方法一样 JVM 会创建一个 toString() 的栈帧放入虚拟机栈中,执行完之后返回一个值。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 凉月の博客!
评论