一,对象实例化

10,对象的实例化,内存布局,访问定位 - 图1

创建对象的六种方式

对象实例化的六个步骤

创建对象的基本代码

  1. public class ObjectTest {
  2. public static void main(String[] args) {
  3. Object obj = new Object();
  4. }
  5. }

使用idea的jclasslib插件查看main方法的字节码(code)

  1. 0 new #2 <java/lang/Object>
  2. 3 dup
  3. 4 invokespecial #1 <java/lang/Object.<init>>
  4. 7 astore_1
  5. 8 return

从字节码来看对象实例化的步骤(这里相当于简化为2步)
image.png

二,对象内存布局

10,对象的实例化,内存布局,访问定位 - 图3

对象头

实例数据

填充数据

示例代码

  1. public class Customer{
  2. int id = 1001;
  3. String name;
  4. Account acct;
  5. {
  6. name = "匿名客户";
  7. }
  8. public Customer(){
  9. acct = new Account();
  10. }
  11. }
  12. class Account{
  13. }

具体内存布局见下图
第10章_图示对象的内存布局.jpg

三,对象访问定位

JVM是如何通过栈帧中的对象引用访问到其内部的对象实例的呢
先通过栈上引用reference找到堆,然后找到方法区
image.png
具体的实现有2种,JVM没有规定,不同虚拟机有自己的实现
1,句柄访问 2,直接指针
具体到我们平时使用的jdk8使用的是直接指针

1,句柄访问

image.png
优点:feference中存储稳定句柄地址,对象被移动(垃圾收集时移动对象很普通)时,只会改变句柄中实例数据指针,feference本身不需要修改

2,直接指针(HotSpot采用)

image.png
优点:节省空间,寻找对象效率快

面试题

  1. 美团
    1. 对象在JVM中是怎么存储的?
    2. 对象头信息里面有哪些东西?
  2. 蚂蚁金服:
    1. 二面:java对象头里有什么?