从0到1理解JVM_对象的创建

JAVA 是一门面向对象的语言,我们所能操作的元素几乎都是对象(连8种基本数据类型都有对应的包装器),在操作对象之前,一般都需要使用new语句(克隆或反序列化时无需 new 也能创建对象)来创建对象,那么,对象是怎么被创建的呢?

安身立命之所

一般的,对象被存储在堆中(栈上分配的对象存储在栈中,Class对象在方法区里)。

创建对象

在创建一个对象之前,首先需要保证对象对应的类已经被加载进方法区。

在类被加载之后,JVM 会在堆中给对象分配一定大小的内存。(至于分配多大的内存,这个在类被加载进方法区后是可以确定的)

对象得到了一块内存,首先做的是将内存中的非对象头部分初始化为0,然后再调用 inti 方法来初始化各个变量的值。

至此,对象就创建完毕并且可以使用。

对象中有什么

在堆中,对象是一块内存,那么,这块内存里都有什么呢?
第一,对象头(包含了对象的哈希码,线程持有锁,GC年龄等),这部分是申请完内存后就不会变,不会变初始化为零值,也不会被 init 方法改变。
第二,对象数据区,这部分内存里存放了该对象的所有变量,会被初始化为零值并被 init 方法改写。
第三,对齐填充,为了符合GC 给对象设下的大小要求,对象需要一定的填充空间。

可见:对象中除了一些必须的信息头外,只有变量,没有代码(代码存放在方法区中的类里,一个类的所有对象都使用同一套代码)。

寻找对象

如何从堆中茫茫的对象里找到我们想要的对象呢?

HotSpot 虚拟机使用了一种指针的方式来定位对象。方法的栈帧里保存了对象的指针(通过该指针能直接找到对象的数据区),数据区中再保留一个类的指针(通过该指针可以知道该对象是属于方法区中的哪个类)。

所以,HotSpot 只需找一次指针就能找到对象,找两次指针就能找到对象对应的类。