【jvm】从字节码角度看待对象创建流程

ops/2024/11/25 13:33:33/

目录

          • 1. 分配内存空间
          • 2. 初始化内存空间为零值
          • 3. 设置对象头
          • 4. 调用构造函数初始化对象
          • 5. 示例代码
          • 6. 字节码指令解析

1. 分配内存空间
  • 1.在Java中,对象存储在堆(Heap)内存中。
  • 2.当创建一个新对象时,JVM首先需要为对象分配一块内存空间。
  • 3.指针碰撞(Bump the Pointer):如果堆内存是规整的(即没有内存碎片),JVM会通过一个指针来跟踪当前已分配的内存位置,并将指针向前移动一段空间来为新对象分配内存。
  • 4.空闲列表(Free List):如果堆内存是不规整的,JVM会维护一个空闲列表来记录哪些内存块是可用的,然后从中选择一个合适的内存块为新对象分配内存。
2. 初始化内存空间为零值
  • 1.在分配内存之后,JVM会将分配的内存空间初始化为零值(即所有的基本数据类型都被初始化为默认值,如int为0,boolean为false等)。
  • 2.这一步骤是为了确保对象字段的初始状态是确定的。
3. 设置对象头
  • 1.对象头(Object Header)包含了一些对象的元数据,比如对象的哈希码(hash code)、GC分代年龄(GC Age)、锁状态标志(lock status)以及类型指针(指向对象的类元数据的指针)。
4. 调用构造函数初始化对象
  • 1.最后一步是调用对象的构造函数来初始化对象的成员变量。
  • 2.这一步骤通常通过invokespecial字节码指令来完成。
  • 3.invokespecial指令用于调用实例初始化方法(方法)、私有方法以及父类方法。
5. 示例代码
  • 1.类代码
public class MyClass {int value;MyClass(int value) {this.value = value;}
}
  • 2.使用javap -c MyClass.class命令查看字节码
public class com.learning.MyClass {int value;com.learning.MyClass(int);Code:0: aload_01: invokespecial #1                  // Method java/lang/Object."<init>":()V4: aload_05: iload_16: putfield      #2                  // Field value:I9: returnpublic static void main(java.lang.String[]);Code:0: new           #3                  // class com/learning/MyClass3: dup4: bipush        106: invokespecial #4                  // Method "<init>":(I)V9: astore_110: return
}
6. 字节码指令解析
  • 1.new #3:new指令用于在堆上分配MyClass类型的新对象实例。#3是对常量池中MyClass类的符号引用。

  • 2.dup:dup指令复制栈顶元素(即新创建的对象引用),这样栈顶就有两个对象引用。

  • 3.bipush 10:bipush指令将操作数栈顶的值设为10(即构造函数的参数)。

  • 4.invokespecial #4:invokespecial指令调用实例初始化方法(即MyClass的构造函数)。#4是对常量池中方法的符号引用。

  • 5.astore_1:astore_1指令将栈顶的对象引用存储到局部变量表的第1个位置(局部变量0是args数组)。


http://www.ppmy.cn/ops/136578.html

相关文章

ONNX 输入batch修改

ONNX 输入batch修改 导出的onnx模型分为静态和动态输入两种&#xff0c;但一般用户会在导出后进行onnxsim操作&#xff0c;导致某些非全卷积的模型修改batch失败&#xff0c;比如transformer类其中reshape的attr属性会固定&#xff0c;修改相当麻烦&#xff0c;需要从源头重新…

Git命令使用与原理详解

1.仓库 # 在当前目录新建一个Git代码库 $ git init ​ # 新建一个目录&#xff0c;将其初始化为Git代码库 $ git init [project-name] ​ # 下载一个项目和它的整个代码历史 $ git clone [url]2.配置 # 显示当前的Git配置 $ git config --list ​ # 编辑Git配置文件 $ git co…

UE5 slate BlankProgram独立程序系列

源码版Engine\Source\Programs\中copy BlankProgram文件夹&#xff0c;重命名为ASlateLearning&#xff0c;修改所有文件命名及内部名称。 ASlateLearning.Target.cs // Copyright Epic Games, Inc. All Rights Reserved.using UnrealBuildTool; using System.Collections.Ge…

Java的包装类及其缓存机制

Java的包装类及其缓存机制 ​ Java 的包装类&#xff08;Wrapper Classes&#xff09;是为每种基本数据类型提供的对象表示。基本数据类型&#xff08;如 int、double 等&#xff09;是非对象类型&#xff0c;而包装类为它们提供了对应的对象版本&#xff0c;以便可以在需要对…

手撕一个阻塞队列

目录 手撕一个阻塞队列代码讲解 手撕一个阻塞队列 要手撕一个阻塞队列&#xff1a;就要实现一个普通的队列&#xff0c;加上阻塞&#xff0c;加上锁 代码 class MyBlockingQueue{private String[] elemsnull;private int tail0;private int head0;private int size0;private…

鸿蒙NEXT开发-Navigation组件导航

注意&#xff1a;博主有个鸿蒙专栏&#xff0c;里面从上到下有关于鸿蒙next的教学文档&#xff0c;大家感兴趣可以学习下 如果大家觉得博主文章写的好的话&#xff0c;可以点下关注&#xff0c;博主会一直更新鸿蒙next相关知识 专栏地址: https://blog.csdn.net/qq_56760790/…

OmniDiskSweeper :一款专为 macOS 设计的磁盘使用分析工具

OmniDiskSweeper 是一款专为 macOS 设计的磁盘使用分析工具&#xff0c;由 The Omni Group 开发。它的主要目的是帮助用户可视化磁盘上的文件和文件夹&#xff0c;并找出占用大量空间的文件&#xff0c;从而帮助用户释放磁盘空间。 OmniDiskSweeper 的特点包括&#xff1a; 简…

【反向迭代器】—— 我与C++的不解之缘(十七)

前言 ​ 在STL中的迭代器部分&#xff0c;之前只关注与正向迭代器&#xff0c;忽视了反向迭代器&#xff1b;现在来看一下反向迭代器到底是个什么东西&#xff0c;以及反向迭代器怎么实现&#xff0c;怎么为之前自己模拟实现的容器增加反向迭代器&#xff1f; 反向迭代器的使用…