NingG +

Understanding the JVM:Java中对象产生初始化过程

实例

直接看下面代码:

class Parent {
	static {
		System.out.println("---static Parnet---");
	}

	public Parent() {
		System.out.println("----Parent----");
	}
}

class Child extends Parent {
	static Other other = new Other();

	public Child() {
		System.out.println("----Child-----");
	}

	Brother b = new Brother();
}

class Brother {
	static {
		System.out.println("---static Brother---");
	}

	public Brother() {
		System.out.println("----Brother----");
	}
}

class Other {
	static {
		System.out.println("---static Other---");
	}

	public Other() {
		System.out.println("---Other---");
	}
}

public class Test {
	public static void main(String[] args) {
		 Child child=new Child();
	}
}

运行结果:

---static Parnet---
---static Other---
---Other---
----Parent----
---static Brother---
----Brother----
----Child-----

具体解释:

简单总结一下:

  1. 父类优先
    1. 父类的 Class,优先
    2. 父类的成员对象和构造函数,优先
  2. 类优先:静态方法和静态对象
  3. 对象
    1. 普通成员:初始化
    2. 构造函数

创建对象

在 Java 语言层面上,我们创建一个对象是如此简单:ClassA intance = new ClassA(); 但是在虚拟机内部,其实经历了非常复杂的过程才完成了这一个程序语句。

上面解决了分配内存的问题,但是也引入了一个新的问题:并发!!!

就刚才的一个修改指针操作,就会带来隐患:对象 A 正分配内存呢,突然!!对象 B 又同时使用了原来的指针来分配 B 的内存。解决方案也有两种:

好了,上面给内存分配了空间,那么内存清零放在什么时候呢?一种情况是分配 TLAB 的时候,就对这块分配的内存清零,或者可以在使用前清零,这个自己实现。

接下来要对对象进行必要的设置,比如

这些信息都放在对象头中。

HotSpot VM,使用上面的字节码规范,对象的头部,包含了指向的类对象地址,因此,属于直接引用方式,访问对象;策略上,还有另一种方式:对象句柄访问对象。

上面的步骤都完成后,从虚拟机角度来看,一个新的对象已经产生了,但是从 Java 程序的视角来看,对象创建才刚刚开始——方法还没有执行,所有的字段都还为零。而这个过程又是一个非常复杂过程,具体可以参考前面的文章,讲解 Java 的对象是如何初始化的。从编译阶段的 constantValue 到准备阶段、初始化阶段、运行时阶段都有涉及。

继续:Java对象创建之后,如何初始化?

对象的内存中布局

首先我们要知道的是:在 HotSpot 虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header)、实例数据(Instantce Data)、对齐补充(Padding)。当然,我们不必要知道太深入,大概知道每个部分的作用即可:

对象的访问定位

对象的访问定位,这个问题要好好整理一下,特别是两个配图。

如何访问对象实例呢?也就是说,如何找到对象实例?两种方式:

insideJVM ed 2-Chapter 5)有详细的配图和介绍,还没有细看

使用句柄

一个对象实例,需要对象的类数据(类型数据)、对象的实例数据,两类数据共同实现一个对象实例。

使用句柄:Java Heap中开辟一个句柄池,JVM Stack中对象reference就是一个句柄,每个句柄指向对象地址和类地址;

疑问:对象引用、对象句柄,是什么?

直接指针

直接指针:JVM Stack中对象reference直接指向对象的实例数据,同时,对象实例数据指向类数据。

使用句柄 vs. 直接指针

两种方式的目的相同:找到对象实例,并访问对象实例。由于实现方式不同,有如下差异:

Top