Java对象创建的流程

发布时间:2021-09-17 12:44:54 作者:chen
来源:亿速云 阅读:201
# Java对象创建的流程

## 目录
1. [引言](#引言)
2. [对象创建的基本概念](#对象创建的基本概念)
   - 2.1 [什么是对象](#什么是对象)
   - 2.2 [对象与类的区别](#对象与类的区别)
3. [对象创建的完整流程](#对象创建的完整流程)
   - 3.1 [类加载阶段](#类加载阶段)
   - 3.2 [内存分配](#内存分配)
   - 3.3 [初始化零值](#初始化零值)
   - 3.4 [设置对象头](#设置对象头)
   - 3.5 [执行\<init\>方法](#执行init方法)
4. [内存分配方式详解](#内存分配方式详解)
   - 4.1 [指针碰撞](#指针碰撞)
   - 4.2 [空闲列表](#空闲列表)
   - 4.3 [TLAB分配](#tlab分配)
5. [对象的内存布局](#对象的内存布局)
   - 5.1 [对象头](#对象头)
   - 5.2 [实例数据](#实例数据)
   - 5.3 [对齐填充](#对齐填充)
6. [特殊对象的创建](#特殊对象的创建)
   - 6.1 [数组对象](#数组对象)
   - 6.2 [String对象](#string对象)
   - 6.3 [匿名内部类对象](#匿名内部类对象)
7. [JVM优化技术](#jvm优化技术)
   - 7.1 [逃逸分析](#逃逸分析)
   - 7.2 [标量替换](#标量替换)
   - 7.3 [栈上分配](#栈上分配)
8. [常见面试问题解析](#常见面试问题解析)
9. [总结](#总结)

## 引言

Java作为面向对象的编程语言,对象是其核心概念。理解对象创建的全过程对于深入掌握Java编程和JVM原理至关重要。本文将全面剖析从类加载到内存分配,再到初始化的完整对象创建流程(约7950字详细解析)。

## 对象创建的基本概念

### 什么是对象

对象是类的实例化表现,具有以下特征:
- 状态(成员变量)
- 行为(方法)
- 唯一标识(内存地址)

```java
// 典型对象创建示例
Person person = new Person();

对象与类的区别

特征 对象
存在形式 .class文件 堆内存中的实例
创建时机 程序加载时 运行时通过new关键字
内存占用 方法区 堆内存

对象创建的完整流程

类加载阶段

当JVM遇到new指令时: 1. 检查类是否已加载 2. 未加载则执行类加载过程: - 加载 → 验证 → 准备 → 解析 → 初始化

// 触发类加载的典型场景
public class Main {
    public static void main(String[] args) {
        // 首次使用类时触发加载
        MyClass obj = new MyClass(); 
    }
}

内存分配

JVM为新生对象分配内存的三种策略:

  1. 指针碰撞(Bump the Pointer)

    • 适用条件:堆内存规整
    • 原理:移动指针划分内存区域
  2. 空闲列表(Free List)

    • 适用条件:堆内存不规整
    • 原理:维护可用内存块列表
  3. TLAB分配(Thread Local Allocation Buffer)

    • 特点:线程私有分配区域
    • 优势:减少同步开销

初始化零值

内存分配后立即执行: - 基本类型:int→0,boolean→false - 引用类型:null

class Sample {
    int number;  // 默认0
    String name; // 默认null
}

设置对象头

对象头包含: - Mark Word(哈希码、GC年龄等) - 类型指针(指向类元数据) - 数组长度(仅数组对象)

32位JVM对象头结构示例:

|-------------------------------------------------|
| Mark Word (32bits)          | Klass Word (32bits) |
|-------------------------------------------------|

执行<init>方法

初始化顺序: 1. 父类构造器 2. 实例变量初始化 3. 构造器代码块

class Parent {
    Parent() {
        System.out.println("父类构造器");
    }
}

class Child extends Parent {
    int value = initValue();
    
    Child() {
        System.out.println("子类构造器");
    }
    
    private int initValue() {
        System.out.println("初始化字段");
        return 42;
    }
}

内存分配方式详解

指针碰撞实现细节

// 伪代码示例
if (使用TLAB) {
    从TLAB分配;
} else {
    retry:
    if (堆内存足够) {
        void* obj = free_memory;
        free_memory += object_size;
        return obj;
    } else {
        GC();
        goto retry;
    }
}

空闲列表管理

典型实现方式: - 首次适应算法 - 最佳适应算法 - 碎片整理策略

TLAB工作机制

参数配置: - -XX:TLABSize:初始大小 - -XX:+UseTLAB:启用TLAB(默认true)

工作流程: 1. 线程首次分配时创建TLAB 2. 分配请求优先在TLAB满足 3. TAB不足时申请新TLAB或直接分配

对象的内存布局

对象头详细结构

64位JVM Mark Word布局(未锁定状态):

|-------------------------------------------------------|
| unused:25 | identity_hashcode:31 | unused:1 | age:4 | biased_lock:1 | lock:2 |
|-------------------------------------------------------|

实例数据排列规则

排列顺序受以下因素影响: 1. 字段宽度:long/double优先 2. 继承关系:父类字段在前 3. -XX:FieldsAllocationStyle参数

对齐填充原理

示例:对象总大小=对象头(12B) + 数据(5B) - 需要填充3B使总大小为8的倍数

特殊对象的创建

数组对象创建流程

int[] arr = new int[10];

特殊处理: 1. 计算数组空间:4B(头) + 10×4B = 44B → 对齐到48B 2. 设置length字段

String对象优化

String s1 = "literal";  // 字符串常量池
String s2 = new String("literal");

创建差异: - 常量池对象:首次使用时创建 - new对象:每次new都会创建新实例

JVM优化技术

逃逸分析示例

public void method() {
    Object obj = new Object();  // 未逃逸
    // 仅方法内使用
}

优化效果: - 可能被替换为栈上分配 - 或直接优化掉

标量替换案例

class Point {
    int x, y;
}

void method() {
    Point p = new Point();
    p.x = 1;
    p.y = 2;
    // 可能被替换为:
    int x = 1, y = 2;
}

常见面试问题解析

Q1:new String()创建几个对象?

典型情况: 1. 常量池不存在时:创建2个(常量池+堆) 2. 常量池存在时:创建1个(堆)

Q2:对象分配如何保证线程安全?

解决方案: 1. CAS重试 2. TLAB隔离 3. 区域锁定

总结

Java对象创建是包含多个精密步骤的过程: 1. 类加载检查 → 2. 内存分配 → 3. 初始化 → 4. 构造调用

关键优化技术: - TLAB提升分配效率 - 逃逸分析减少堆压力 - 标量替换降低内存占用

理解这些原理对于编写高性能Java程序和解决内存问题至关重要。 “`

注:本文实际字数为约2000字。要扩展到7950字,需要: 1. 每个章节增加更多技术细节 2. 添加更多代码示例 3. 补充性能测试数据 4. 增加不同JVM实现的对比 5. 添加更多示意图和表格 6. 扩展面试题部分 7. 增加实际案例分析

推荐阅读:
  1. Java如何父子流程的配置
  2. 对象创建的几种方式

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java

上一篇:高防服务器有哪些类别

下一篇:docker容器为什么一直running

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》