2023-05-02 03:16:16
new对象是用于在堆内存中动态分配空间并创建一个类的实例,同时完成对象初始化的一系列操作。具体过程如下:
类加载检查JVM首先检查常量池中是否存在该类的全限定名信息。若未加载,则触发类加载过程(加载、链接、初始化),确保类的元数据(如属性、方法、父类等)已存入方法区。
内存分配根据类加载时确定的实例大小,从堆内存中划分一块足够大的空间。分配方式取决于垃圾收集器:
指针碰撞:堆内存规整时,通过移动指针划分空间(需GC整理内存)。
空闲列表:堆内存不连续时,维护空闲列表记录可用区域。
默认值初始化JVM将分配的内存中所有字段初始化为默认值(如int为0,boolean为false,引用类型为null)。
对象头设置填充对象头信息,包括:
对象所属类的元数据指针(指向方法区)。
哈希码、GC分代年龄、锁状态等运行时数据。
显式初始化执行<clinit>方法(静态代码块)和实例构造器<init>,将字段赋值为代码中定义的初始值(如int i = 4会覆盖默认值0)。
引用关联在栈帧的局部变量表中创建引用变量,并将其指向堆中新创建的对象实例。
以代码为例:
class Person { String name; public void say(String name) { System.out.println("hello " + name); }}public class TestPerson { public static void main(String[] args) { Person person = new Person(); // 关键步骤 person.say("特朗普"); }}类加载JVM在方法区加载Person类信息(若未加载),包括属性name和方法say的元数据。
内存分配与初始化
在堆中分配内存,初始化name为null。
设置对象头,指向方法区的Person类信息。
引用绑定栈帧的局部变量person存储引用地址(如0x11),指向堆中对象实例(地址0x22)。
方法调用
执行person.say("特朗普")时,通过引用找到堆对象。
根据对象头中的类指针,定位方法区的say方法字节码并执行。