美文网首页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