图文深入理解java对象从创建到回收都经历了什么

news2025/1/18 17:01:13

1. 前言:

每个java对象都是有生命周期的,就像一个人的生命一样,从孕育到出生到成长变老最后由归于自然。笔者认为,Java对象的整个生命周期可以分为两个大的阶段:即创建阶段和运行阶段(包含对象的回收和消亡)。本篇将会图文深入介绍java对象的整个生命过程。
一般人平时看到java其实只是冰山的一角–java世界的冰上部分,冰下的java世界其实更精彩。
在这里插入图片描述

1.java对象的创建阶段

在Java中,对象的创建是一个复杂但有序的过程,涉及多个步骤和底层的JVM(Java虚拟机)运作。java对象的创建过程近似于下图,详细过程如下:
在这里插入图片描述

1. 类的加载

其实,在创建对象之前,JVM需要确保类已经被加载、链接和初始化,但这个过程属于对象的孕育阶段,就像一个人在母体一样,所以也是算作对象的创建阶段:

  1. 加载(Loading):将类的字节码从文件系统中读取到内存中。
  2. 链接(Linking),又可分为三个阶段:
    验证(Verification):确保字节码是合法的,不会违反Java语言的语义规则。
    准备(Preparation):为类的静态变量分配内存并设置为默认值(例如,int为0,引用类型为null)。
    解析(Resolution):将符号引用转换为直接引用(例如,将方法名转换为方法地址)。
  3. 初始化(Initialization):执行类的初始化代码,包括静态变量的赋值和静态块的执行。

2. 分配内存

在这里插入图片描述

在类加载完成后,JVM会在堆内存中为对象分配空间。实际运作过程如下:

  1. 判断是否需要线程安全:如果多个线程同时创建同一个类的对象,JVM需要确保内存分配的原子性。这可以通过两种方式实现:
  2. 使用同步机制:确保每次只有一个线程可以分配内存。
  3. 使用本地线程分配缓冲区(TLAB,Thread Local Allocation Buffers):每个线程在堆内存中预先分配一块私有空间,用于对象的分配。这样可以减少同步的开销。
  4. 分配内存:在堆中分配内存空间,具体方式取决于JVM使用的垃圾回收器。例如,在使用Serial GC时,直接分配在Eden区;在使用G1 GC时,根据对象的预期存活时间选择适当的区域。

3. 初始化内存

分配的内存空间初始化为零(基本数据类型,对象引用类型初始化为null)。这一步确保了对象的字段在构造方法执行之前处于确定的状态。

4. 设置对象头

每个对象在内存中都有一个对象头(Object Header),用于存储对象的一些元数据,包括:
哈希码(Hash Code):用于快速查找对象,例如在HashMap中。
GC分代年龄(GC Age):记录对象在垃圾回收过程中经过的次数,用于决定对象是否晋升到老年代。
锁状态标志(Lock Status):记录对象是否被锁定,以及锁的类型(轻量级锁、重量级锁等)。
类元数据指针(Class Metadata Pointer):指向对象的类元数据,用于在运行时访问类信息。

5. 执行构造方法

在对象内存分配和初始化之后,JVM会调用对象的构造方法来完成对象的初始化。构造方法中的代码会设置对象的字段值并执行其他初始化逻辑。

6. 返回引用

构造方法执行完毕后,JVM会将新创建对象的引用返回给调用者。此时,对象已经完全创建并可以使用了。

java对象的运行阶段

在这里插入图片描述

  1. 对象的使用(Usage)
    一旦对象被创建并初始化,它就可以被应用程序使用。对象通过其引用变量进行访问和操作。演示如下:
public class Person {  
    static String period = "GESTATION";  
    int instanceVar;  
    static {  
        // 静态初始化块  
        System.out.println("这是我的孕育阶段");  
    }  
  
    public void say() {  
        System.out.println("我就是我,不一样的烟火!");  
    }  
  
    public Person() {  
        // 构造函数  
        System.out.println("构造函数被执行");  
        this.instanceVar = 0;  
    }  
  
    public static void main(String[] args) {  
        Person person = new Person();  
        System.out.println("我出生了");  
        // 可以调用person的say方法  
        person.say();  
    }  
}
  1. 对象的垃圾回收(Garbage Collection)
    当对象不再被应用程序使用时,JVM的垃圾回收器(Garbage Collector, GC)会自动回收该对象所占用的内存空间。Java使用自动垃圾回收机制,程序员不需要手动释放内存。垃圾回收的判断依据主要是对象的可达性(Reachability),即对象是否从根集合(Root Set)可达。常见的可达性状态包括:
    可达(Reachable):对象可以从根集合直接或通过其他可达对象间接到达。
    可复活(Resurrectable):对象的所有引用都被释放,但在某个时间点它可能再次变为可达。
    不可达(Unreachable):对象既不是可达的,也不是可复活的。这些对象会被垃圾回收器回收。
  2. 对象的终结(Finalization)
    Java提供了一个finalize()方法,允许对象在垃圾回收之前执行清理操作。然而,需要注意的是,finalize()方法并不保证会被及时调用,也不应该被用作主要的清理机制。从Java 9开始,finalize()方法已被弃用,建议使用java.lang.ref.Cleaner和java.lang.ref.PhantomReference来替代。
  3. 对象的销毁(Destruction)
    对象的销毁是指对象所占用的内存空间被垃圾回收器回收的过程。在Java中,对象的销毁是自动进行的,程序员无法直接控制。

本篇完结。
码字不易,宝贵经验分享不易,请各位支持原创,转载注明出处,多多关注作者,家人们的点赞和关注是我笔耕不辍的动力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2214217.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

19009 后缀表达式

### 思路 1. **输入处理**:读取输入的后缀表达式,去掉末尾的符号。 2. **使用栈计算后缀表达式**: - 遍历表达式中的每个字符。 - 如果是数字,压入栈中。 - 如果是运算符,从栈中弹出两个数字进行运算&#xf…

若依前后端分离版本el-select下拉框字典如何设置默认值。

在若依前后端分离框架中,如何给下拉框设置默认值,刚入门的小伙伴,可能会不知道如何去做。 本章教程,主要以用户管理模块中的添加用户举例说明如何设置用户性别默认值为男。 解决思路 首先,我们需要找到打开新增页面的方…

解锁机器学习的新维度:元学习的算法与应用探秘

引言 在机器学习快速发展的今天,元学习(Meta-Learning)作为一种新兴的方法论,受到了越来越多的关注。元学习的主要目标是使模型能够在面对新任务时迅速适应,通常只需极少的样本。这一能力在现实应用中尤为重要&#x…

linux点灯驱动实验实现

1.用字符串实现LED灯驱动编写 LED灯连接到的是GPIO1_IO03口上,所以我们只需要初始化这个引脚时钟,配置这个引脚和电器属性,我们就可以通过寄存器对LED进行控制。 2.内存映射 与STM32等芯片不同的是,linux系统对引脚地址操作不是…

光平面标定代码

本篇文章主要给出光平面标定代码,鉴于自身水平所限,如有错误,欢迎批评指正。(欢迎进Q群交流:874653199) 数据分为棋盘格数据和激光条数据,激光条数据为在第22个位姿至第26个位姿下打在棋盘格标定…

短视频矩阵多账号发布源码

在构建一个短视频矩阵系统时,我们需综合考虑多个关键领域:用户接口设计、后端处理逻辑、数据存储与维护以及系统安全性。该系统的主要功能模块包括: 1. 用户界面(UI)设计 - 登录/注册功能,允许用户创建并管…

解锁 SDKMAN!:最新教程与全面简介

SDKMAN! 是一个用于管理开发工具的软件开发工具包管理器,特别适用于 JVM 生态系统。 官网地址:https://sdkman.io/ 多版本管理:允许用户在同一台机器上安装和管理多个版本的 SDK(如 Java、Groovy、Scala、Kotlin 等)。 简单安装:通过简单的命令行命令可以安装、更新和卸载…

在三维可视化项目中,B/S和C/S架构该如何选择?

一、什么是B/S和C/S 在3D数据可视化中,有两种常见的架构模式:BS(Browser/Server)和CS(Client/Server) B/S模式 B/S模式是指将3D数据可视化的逻辑和处理放在服务器端,而在客户端使用浏览器进行…

Nature 正刊丨生物分子冷凝物介导内体膜的弯曲和断裂

01摘要 多囊体是通过降解膜结合的货物蛋白1,2,3参与细胞质量控制的关键内体隔室。消耗ATP的ESCRT蛋白机制通过多泡体膜的内陷和断裂形成管腔内囊泡,介导膜结合货物蛋白的捕获和吞噬4,5。在这里,我们报告说,植物ESCRT组分FREE16形成与膜结合的…

Hadoop集群基础搭建

目录 一.虚拟机安装 1.配置虚拟机的ip 2.配置本机的ip 3.新建虚拟机 4.克隆三台虚拟机 二.虚拟机网络配置 1.修改ip配置 2.配置主机名和主机映射 3.配置SSH免密登陆 三.安装JDK 1.tar命令解压JDK安装包 2.配置JDK的环境变量 四.安装Hadoop 1.tar命令解压Hadoop安…

Python数据分析-matplotlib数据可视化

1. 初识Matplotlib matplotlib是 Python 最流行的绘图工具之一,广泛用于数据可视化。 1.1基本图表绘制: 图表名称表示函数散点图plt.scatter(x, y)柱状图plt.bar(x, height)折线图plt.plot(x, y)直方图plt.hist(x, bins)箱线图plt.boxplot(x)热力图p…

使用python从头开始预训练RoBERTa模型

本文将介绍如何使用Hugging Face库从头开始构建一个预训练Transformer模型。该模型称为 KantaiBERT。 #title Step 1: Loading the Dataset #1.Load kant.txt using the Colab file manager #2.Downloading the file from GitHubant !curl -L https://raw.githubusercontent.c…

Linux学习第一天

目录 1.引入 计算机的组成(图解) 操作系统是什么 操作系统的功能 操作系统的组成(图解) 操作系统内核的功能 常见的操作系统 2.Libux的学习 Linux的特点 Linux应用领域 搭建Linux学习环境 下载 创建虚拟机 新建虚拟机…

短视频矩阵开发,抖音新机遇(技术开发框架解析)

开发前言: 抖音短视频矩阵系统技术开发框架主要利用了VUE, Spring Boot、Django等技术。本技术文档适用于短视频矩阵源码的开发和部署。 #短视频矩阵源码开发部署 #抖音矩阵源码开发 #抖音矩阵源码 #抖音矩阵开发 抖音短视频矩阵系统的技术开发框架可以…

P1320压缩技术(续集版

P1320压缩技术(续集版 感觉这题还是蛮难的对我来说,通过这题我才知道原来字符串输入不碰到空格就会一起输进来 我参考了一写题解自己又写了自己的解法,vs中的scanf_s和scanf()用法不太一样,之前按scanf写法写一直在报错&#xff…

彻底掌握Android中的Lifecycle

彻底掌握Android中的Lifecycle Lifecycle 是一个生命周期感知型组件,属于 Jetpack 组件库中的一部分,其核心功能是将组件(如Activity 和 Fragment)的生命周期状态通知给观察者(LifecycleObserver)。观察者…

指针 + 数组 较为复杂凌乱的 【笔试题】

2024 - 10 - 10 - 笔记 - 25 作者(Author): 郑龙浩 / 仟濹(CSDN 账号名) 【指针 数组】的 各种题型(笔试题) 来自于鹏哥的网课&#xff0c;我做一下笔记 119. 【C语言进阶】笔试题详解&#xff08;4&#xff09;_哔哩哔哩_bilibili ① 题 #include <stdio.h> int m…

VUE 开发——Vue学习(三)—— 智慧商城项目

目录 解释各个模块 api接口模块&#xff1a;发送ajax请求的接口模块utils工具模块&#xff1a;自己封装的一些工具方法模块components组件模块&#xff1a;全局通用的组件router路由模块&#xff1a;封装要所有路由views&#xff1a;各个页面assets&#xff1a;各种资源 van…

JAVA软开-面试经典题(7)-字符串常量池

字符串常量池 1.定义&#xff1a;字符串常量池&#xff08;String Constant Pool&#xff09;&#xff0c;用于存放字符串常量的运行时内存结构&#xff0c;其底层的实现为Hashtable。 【注意】 在JDK1.6之前&#xff0c;字符串常量池中只会存放具体的String实例&#xff0c;在…

MySQL基础探秘(3)

前面那篇文章是简单介绍了往数据库中插入数据&#xff0c;以及对数据进行有些改动。 但是&#xff0c;细想下&#xff0c;数据能够无限制&#xff0c;无约束进行插入吗&#xff1f; emm……显然是不行的&#xff0c;不然数据就乱套了&#xff0c;看起来不美观。 所以要对数据…