创建一个对象时发生什么

从类加载到对象分配内存过程:

1、什么是TLAB?

从内存模型角度,对Eden区域继续进行划分,JVM在Eden空间内为每一个线程分配了一个私有缓存区域。

多线程同时分配内存时,使用TLAB可以避免一系列的非线程安全问题,同时还能提升内存分配的吞吐量,这种内存分配方式称为快速分配策略。

TLAB 在 JVM 中默认启用(通过参数 -XX:+UseTLAB控制)。线程启动时,JVM 从 Eden 区划分一块内存作为其 TLAB。初始大小由 JVM 自适应计算(通常占 Eden 区的 1%),也可通过参数 -XX:TLABSize手动设置。

2、创建对象的方式?

  1. 通过new 关键字
  2. Class的newInstance()(官网不建议使用)
  3. Constructor的newInstance(Xxx)
  4. 使用clone()
  5. 使用反序列化
  6. 第三方库Objectsis

3、创建一个对象经历哪些步骤?

  1. 判断对象对应的类是否加载、链接、初始化

  2. 为对象分配内存:根据内存是否规整,分配方式有所不同,

    1. 如果内存规整,则采用指针碰撞的方式;
    2. 如果内存不规整,则需要维护一个列表,按空闲列表分配
  3. 处理并发安全问题:有两种方式处理并发问题,

    1. 采用CAS+失败重试保证更新的原子性
    2. 为每一个线程预分配一块TLAB
  4. 初始化分配的空间: 为所有的属性设置默认值,保证对象实例字段在不赋值可以使用

  5. 设置对象的对象头

  6. 执行Init方法进行初始化(包括:构造器,实例代码块,属性显示赋值)

4、一个对象在内存空间长什么样?

  • 对象头(Header)
  • 实例数据(Instance Data)
  • 对齐填充(Padding)

对象头主要包含两部分:运行时元数据、类型指针,如果是数组,还需要记录数组的长度。运行时元数据主要包含哈希、GC分代年龄和锁相关信息。类型指针指向类的元数据。

实例数据包含了父类变量和自己类变量数据

对齐填充是非必要的

看下面一段代码,在内存空间是如何分布的

代码:

arduino 复制代码
package com.test.jvm;
​
public class InstanceHeapTest {
    public static void main(String[] args) {
        Customer cust = new Customer(1, "张三", new Account(1, "张三"));
​
    }
}
​
​
class Customer {
    private int id;
    private String name;
    private Account acct;
​
    public Customer(int id, String name, Account acct) {
        this.id = id;
        this.name = name;
        this.acct = acct;
    }
    // get set 方法省略
    
}
​
class Account {
    private int id;
    private String name;
​
    public Account(int id, String name) {
        this.id = id;
        this.name = name;
    }
    // get set 方法省略
}

内存分布示意图:

相关推荐
bksczm4 小时前
InnoDB 行格式详解:DYNAMIC / COMPACT / COMPRESSED / REDUNDANT
java·开发语言·数据库
liangbo75 小时前
Spring系列03:Bean 的三种注册方式
java·spring
余槐i5 小时前
MySQL 8.0 联合索引走错:为什么加了索引查询反而从 200ms 变成 8s
java·spring boot·mysql·docker·性能优化
SL_staff5 小时前
制造业订单交付总在最后一刻爆雷?用结构化计划模板打通跨系统协同断点
java·开源·全栈
做科研的周师兄5 小时前
【R语言实战】MixSIAR 氢氧同位素水源解析全流程:从混合空间校验到贝叶斯 MCMC 收敛诊断(后附完整代码)
java·大数据·开发语言
有点小困9775 小时前
Spring Boot 异步任务 ClassLoader 踩坑实录:ClassNotFoundException 的诡异真相
java
aiks_yuan5 小时前
Java 正则表达式很慢怎么办:Pattern 预编译只快 2~5 倍,真正卡死线程的是回溯(JDK 8、11、17 实测)
java
用户3721574261355 小时前
C# 填写 PDF 交互式表单:文本框、复选框、单选按钮和下拉列表
java
IT枫斗者枫哥5 小时前
Java 退款请求超时,先查原单还是重试?
java·后端
特立独行的猫A5 小时前
我用仓颉写了个多平台发文工具:一份 Markdown,一条命令发六个平台
java·后端·python