JVM---对象

 

/**
     *  【对象的实例化】
     *      <创建对象的方式>
     *          1、new
     *              a, new XXX
     *              b, XXX.static方法
     *              c, XXXBuilder/ XXXFactory的方法
     *          2、反射
     *              a, Class的newInstance
     *                  ***空参构造器,权限必须是public
     *              b, Constructor的newInstance
     *                  ***空参(或带参)构造器,权限不限制
     *          3、clone
     *              ***不调用构造器
     *                  当前类需要实现Cloneable接口,实现clone()
     *          4、反序列化
     *              从网络、文件中获取 一个对象的二进制字节流
     *          5、三方库Objenesis
     *              动态生成对象
     *
     *      <创建对象的步骤>
     *
     *              Object object = new Object();
     *
     *              0: new           #2                  // class java/lang/Object
     *              3: dup
     *              4: invokespecial #1                  // Method java/lang/Object."<init>":()V   对象成员变量显式初始化
     *              7: astore_1
     *              8: return
     *
     *
     *              1,判断对象对应的类是否加载、链接、初始化
     *                  当 JVM遇到new指令,首先去检查new指令的参数 能否在方法区的常量池中找到该类的引用,并检查该类是否被加载、链接、初始化:
     *                      如果没有,在双亲委派的模式下,使用当前类加载器查找对应的class文件:
     *                          若没有找到文件,抛出ClassNotFoundException;
     *                          找到文件,进行类加载;
     *
     *              2,计算 对象所占堆内存大小,然后在堆中分配内存给新对象;
     *                  如果 对象成员变量 是引用类型,只需要分配引用变量空间即可,4字节;
     *                      byte,short,int,char,boolean,float,引用类型 都是 4个字节;
     *                      double,long是8个字节;
     *
     *                  处理 内存分配 并发安全问题
     *                      1、使用CAS,保证操作的原子性
     *                      2、每个线程 预先 分配 一个 TLAB;
     *
     *              3,给 对象的实例属性 默认初始化;
     *
     *              4,设置 对象头
     *                  将对象的所属类、对象的hashcode、对象的GC信息、锁信息等 存储到对象头;
     *
     *              5,执行构造器<init>方法 进行 对象成员变量显式初始化(顺序执行):
     *                  aa,成员变量 显式 初始化;
     *                  bb,执行 实例代码块;
     *                  cc,执行 类的构造器;
     *                  dd,将 对象的地址 赋值给 引用变量
     *
     *
     *      <给对象属性赋值的操作>
     *          1、属性的默认初始化
     *          2、属性的显式初始化
     *              属性显式赋值、代码块显式赋值、构造器显式赋值...
     *
     *
     *      <类的构造器<init>方法>
     *          public class User {
     *
     *              private String name = "jack";
     *              private int age = 10;
     *
     *              {
     *                  name = "rose";
     *              }
     *
     *              public User(){
     *                  this.age = 11;
     *              }
     *
     *              public User(String name){
     *                  this.name = name;
     *              }
     *
     *              public User(int age){
     *                  this.age = age;
     *              }
     *          }
     *
     *          空参构造器<init>
     *              0 aload_0
     *              1 invokespecial #1 <java/lang/Object.<init>>
     *              4 aload_0
     *              5 ldc #2 <jack>
     *              7 putfield #3 <com/an/object/User.name>
     *              10 aload_0
     *              11 bipush 10
     *              13 putfield #4 <com/an/object/User.age>
     *              16 aload_0
     *              17 ldc #5 <rose>
     *              19 putfield #3 <com/an/object/User.name>
     *              22 aload_0
     *              23 bipush 11
     *              25 putfield #4 <com/an/object/User.age>
     *              28 return
     *
     *          String参数构造器<init>
     *              0 aload_0
     *              1 invokespecial #1 <java/lang/Object.<init>>
     *              4 aload_0
     *              5 ldc #2 <jack>
     *              7 putfield #3 <com/an/object/User.name>
     *              10 aload_0
     *              11 bipush 10
     *              13 putfield #4 <com/an/object/User.age>
     *              16 aload_0
     *              17 ldc #5 <rose>
     *              19 putfield #3 <com/an/object/User.name>
     *              22 aload_0
     *              23 aload_1
     *              24 putfield #3 <com/an/object/User.name>
     *              27 return
     *
     *          int参数构造器<init>
     *              0 aload_0
     *              1 invokespecial #1 <java/lang/Object.<init>>
     *              4 aload_0
     *              5 ldc #2 <jack>
     *              7 putfield #3 <com/an/object/User.name>
     *              10 aload_0
     *              11 bipush 10
     *              13 putfield #4 <com/an/object/User.age>
     *              16 aload_0
     *              17 ldc #5 <rose>
     *              19 putfield #3 <com/an/object/User.name>
     *              22 aload_0
     *              23 iload_1
     *              24 putfield #4 <com/an/object/User.age>
     *              27 return
     */

  

/**
     *  【对象的内存布局】
     *              <对象头(Object Header)>
     *                      a,MarkWord(运行时元数据):
     *                          hashCode、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳
     *                      b,类型指针
     *                          指向 方法区中该对象所属的类型;
     *
     *                      ***如果是数组,还包括 数组长度;
     *
     *              <实例数据(Instance Data)>
     *                  对象真正存储的有效信息
     *                      包括 程序自己定义的属性、从父类继承的属性
     *                  ***规则:
     *                      对象中先放 父类属性,再放 子类属性;
     *
     *              <对齐填充(padding)>
     *                  非必须,起到占位符的作用;
     *
     *              eg:
     *              public class Account {}
     *
     *              public class Customer {
     *
     *                  int id = 1001;
     *                  String name;
     *                  Account acc;
     *
     *                  {
     *                      name = "匿名客户";
     *                  }
     *
     *                  public Customer(){
     *                      acc = new Account();
     *                  }
     *              }
     *
     *
     *              Customer cust = new Customer();
     */

  

 

/**
     *  【对象访问】
     *      JVM 如何 通过栈桢中的对象引用 访问到 对象实例的?
     *          通过栈桢中 局部变量存储的引用类型的对象实例的具体内存地址;
     *
     *      访问方式:
     *          直接指针(Hotspot采用)、句柄访问
     */  

直接访问

 

 

句柄访问

 

posted on 2022-04-24 15:53  anpeiyong  阅读(14)  评论(0编辑  收藏  举报

导航