美文网首页JVM
17-对象的实例化、内存分配与访问定位演示

17-对象的实例化、内存分配与访问定位演示

作者: 紫荆秋雪_文 | 来源:发表于2021-05-04 17:31 被阅读0次

    一、对象的实例化

    1.1、创建对象常用的方式

    -1、最常用的方式

    new Object()
    
    • 2、Class的newInstance
    • 3、Constructor的newInstance(xxx)
    • 4、使用clone()
    • 5、使用反序列化
    • 6、第三方库Objenesis

    1.2、创建对象的过程

    • 1、判断对象对应的类是否加载、链接、初始化
    • 2、为对象分配内存
      • 如果内存规整:指针碰撞
      • 如果内存不规整:虚拟机需要维护一个列表、空闲列表分配
    • 3、处理并发安全问题
      • 采用CAS配上失败重试保证更新的原子性
      • 每个线程预先分配一块TLAB
    • 4、初始化分配到空间:所有属性设置默认值,保证对象实例字段在不赋值时可以直接使用
    • 5、设置对象的对象头
    • 6、执行 init 方法进行初始化

    二、对象的内存布局

    2.1、对象头(Header)

    • 运行时元数据(Mark Word)
      • 1、哈希值
      • 2、GC分代年龄
      • 3、锁状态标志
      • 4、线程持有的锁
      • 5、偏向线程ID
      • 6、偏向时间戳
    • 类型指针:指向类元数据InstanceKlass,确定该对象所属的类型

    2.2、实例数据(Instance Data)

    • 它是对象真正存储的有效信息,包括程序代码中定义的各种类型的字段(包括从父类继承下来的和本身拥有的字段)
    • 相同宽度的字段总是被分配在一起
    • 父类中定义的变量会出现在子类之前
    • 如果CompactFields参数为true(默认为true):子类的窄变量可能插入到父类变量的空隙

    2.3、对齐填充(Padding)

    • 不是必须的,也没特别含义,仅仅起到占位符的作用

    三、对象的访问定位

    • 创建对象的目的是为了使用
    • JVM是如何通过栈帧中的对象引用访问到其内部的对象实例的
    • 对象访问方式主要有两种
      • 1、句柄访问 image.png
      • 2、直接指针(HotSpot采用) image.png

    四、实例分析

    4.1、code

    package com.lkty.method;
    
    public class Customer {
        int id = 10086;
        String  name;
        Account account;
    
        {
            name = "匿名客户";
        }
    
        public Customer() {
            this.account = new Account();
        }
    }
    
    class Account {
    
    }
    
    

    4.2、测试代码

    package com.lkty.method;
    
    public class CustomerTest {
        public static void main(String[] args) {
            Customer customer = new Customer();
        }
    }
    
    image.png

    相关文章

      网友评论

        本文标题:17-对象的实例化、内存分配与访问定位演示

        本文链接:https://www.haomeiwen.com/subject/lgwtdltx.html