Java对象的创建过程

tech2024-10-15  7

关于对象的创建过程一般是从new指令开始的,整个流程如下所示:

一、类加载检查

虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到这个类的符号引用,并且检查这个符号引用代表的类是否已被加载过、解析和初始化过。如果没有,那必须先执行对应的类加载过程。

二、分配内存

在类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象所需的内存大小在类加载完后便可确定,为对象分配空间的任务等同于把一块确定大小的内存从Java堆中划分出来。分配方式有:“指针碰撞”和”空闲列表“两种,选择哪种分配方式由Java 堆是否规整决定,⽽Java堆是否规整⼜由所采⽤的垃圾收集器是否带有压缩整理功能决定。

三、初始化零值

内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值,这一步操作保证了对象的实例字段在Java代码中可以不赋初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。

为对象分配完堆内存之后,JVM会将该内存(除了对象头区域)进行零值初始化,这也就解释了为什么JAVA的属性字段无需显示初始化就可以被使用,而方法的局部变量却必须要显示初始化后才可以访问。

四、设置对象头

初始化零值完成之后,虚拟机要对对象进⾏必要的设置,例如这个对象是那个类的实例、如何才能找到类的元数据信息、对象的哈希吗、对象的 GC 分代年龄等信息。 这些信息存放在对象头中。 另外,根据虚拟机当前运⾏状态的不同,如是否启⽤偏向锁等,对象头会有不同的设置⽅式。

HotSpot虚拟机实现的JAVA对象包括三个部分:对象头、实例字段和对齐填充字段,具体内容如下图所示: 其中要注意的是,实例字段包括自身定义的和从父类继承下来的(即使父类的实例字段被子类覆盖或者被private修饰,都照样为其分配内存)。

五、执行init方法:

在上⾯⼯作都完成之后,从虚拟机的视⻆来看,⼀个新的对象已经产⽣了,但从Java 程序的视⻆来看,对象创建才刚开始, < init > ⽅法还没有执⾏,所有的字段都还为零。所以⼀般来说,执⾏ new 指令之后会接着执⾏ < init > ⽅法,把对象按照程序员的意愿进⾏初始化,这样⼀个真正可⽤的对象才算完全产⽣出来。

至此,一个对象就被创建完毕,此时,一般会有一个引用指向这个对象。在JAVA中,存在两种数据类型,一种就是诸如int、double等基本类型,另一种就是引用类型,比如类、接口、内部类、枚举类、数组类型的引用等。引用的实现方式一般有两种,如下图所示:

最新回复(0)