本文中的对象限于HotSpot虚拟机中
对象创建
- 虚拟机遇到new指令,先去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并检查这个符号引用代表的类是否已被加载、解析和初始化
- 如果没有,先执行相应的的类加载过程,在类加载检查通过后,虚拟机为新生对象分配内存
- 内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值,保证对象的实例字段在Java代码中不赋初始值就能直接引用
- 虚拟机对对象进行必要的设置,如对象哈希码,对象属于哪个类,对象的GC分代年龄等信息
对象的内存布局
- 对象在内存存储的布局分为三块区域:对象头、实例数据、对象填充
- 对象头包括两部分信息:第一部分用于存储对象自身的运行时数据,第二部分是类型指针,即对象指向它元数据的指针
- java元数据:元数据是指用来描述数据的数据,更通俗一点,就是描述代码间关系,或者代码与其他资源(例如数据库表)之间内在联系的数据。在一些技术框架,如struts、EJB、hibernate就不知不觉用到了元数据。对struts来说,元数据指的是struts-config.xml;对EJB来说,就是ejb-jar.xml和厂商自定义的xml文件;对hibernate来说就是hbm文件。
对象的访问定位
目前主流方式是使用句柄和直接指针。区别在于使用句柄方式会在java堆中维护一个句柄池(到对象实例数据的指针和到对象类型数据的指针),栈中对象引用指向句柄池再由句柄池分别指向对象实例数据和对象类型数据。直接指针在于栈中引用直接指向对象实例数据。