对象创建
在java的程序运行期间,无时无刻没有对象的创建,虚拟机在遇到一条new的字节码指令后,就会去检查这个指令的参数是否在运行时常量池有相对应的符号引用,并且检查这个符号引用所代表的类是否被加载了,如果没有就由虚拟机执行类的加载
类加载检查后就要位新生对象分配内存,对象所需要的内存空间在类加载完成后就可以确定,在Java堆为对象分配空间,其实就是把一个确定大小的内存划分出来存放对象,如果java堆中的内存是非常规整的,所有使用过的内存放在一边,空闲的内存放在另一边,中间放这一个指针作为空间分界点的指示器,那么在给新生对象分配空间时,只需要指针向空闲内存移动一个对象大小的区域即可,而Java堆需要维护一个记录可用和已经使用的内存区域,并在分配对象空间时更新列表,这种方法就叫做指针碰撞。
由此对象在Java堆中的内存就分配完毕了。
但此时对象并没有创建完毕,因为class的init的方法还没有执行,所有类里面的字段还是默认的零值
对象的内存分配
对象在java堆中的信息,大概分为对象头、实例数据、对齐填充三个部分
对象的访问定位
对象的访问定位的实现主流的有两种方式,一种是使用句柄另一种是直接指针(使用对象头中的类型指针)
使用句柄
如果是使用句柄的方式,需要在java堆中分配一块句柄池的内存,优点是对象被移动也只会改变句柄池中的实例数据的指针
直接指针
直接指针的方式就可以使用对象头中的类型指针了,优点是对比使用句柄,少了一次指针访问的开销,使得访问的速度更快,缺点就是对象移动比较麻烦