创建一个对象时发生什么

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

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 方法省略
}

内存分布示意图:

相关推荐
一叶飘零_sweeeet3 小时前
SpringBoot 整合 Kafka 的实战指南
java·spring boot·kafka
间彧3 小时前
Java Stream reduce方法深度解析
java
FrankYoou3 小时前
spring boot autoconfigure 自动配置的类,和手工 @configuration + @bean 本质区别
java·spring boot·后端
lovebugs3 小时前
JVM内存迷宫:破解OutOfMemoryError的终极指南
java·后端·面试
Swift社区3 小时前
66项目中 Spring Boot 配置文件未生效该如何解决
java·spring boot·后端
零雲3 小时前
66java面试:可以讲解一下mysql的索引吗
java·mysql·面试
间彧3 小时前
Stream API:mapToInt()使用
java
FOWng_lp3 小时前
66Mac电脑Tomcat+Java项目中 代码更新但8080端口内容没有更新
java·开发语言·macos·tomcat
盖世英雄酱581363 小时前
今天下午一半的系统瘫痪了
java·后端·架构