【从零学习JVM|第三篇】类的生命周期(高频面试题)

news2025/6/13 11:28:57

前言:

在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。

目录

​编辑前言:

类的生命周期

类的加载阶段

核心任务

连接阶段

 验证(Verification)

 准备(Preparation)

解析(Resolution)

初始化阶段

() 方法特性

不会导致初始化

初始化触发条件(严格规定)

使用阶段

卸载阶段

面试题

总结


类的生命周期

一个类的生命周期分为五个阶段,分别是加载,连接,初始化,使用和卸载。

类的加载阶段

加载是将类的字节码文件(.class)加载到 JVM 内存的过程,类加载器会通过不同的形式,去得到字节码文件的内容,然后通过JVM,把内容加载到方法区和堆区,而我们开发者只能访问到堆区的内容,方法区我们是访问不到的,堆区的内容是字节码文件的核心内容。

核心任务

  1. 查找字节码

    • 通过类的全限定名查找字节码文件

    • 搜索路径:类路径(classpath)、JAR 文件、网络资源等

  2. 创建类结构

    • 解析字节码并创建对应的类数据结构

    • 在方法区(元空间)存储类的运行时常量池、字段和方法信息

  3. 创建 Class 对象

    • 在堆内存中创建 java.lang.Class 对象

    • 该对象作为访问类元数据的入口

连接阶段

在加载阶段结束后进入连接阶段,连接阶段分为三个子阶段,确保类字节码的正确性和可用性

 验证(Verification)

确保字节码符合 JVM 规范和安全要求:

  • 文件格式验证:魔数(0xCAFEBABE)、版本号等

  • 元数据验证:语义检查(是否有父类、final类是否被继承等)

  • 字节码验证:数据流和控制流分析

  • 符号引用验证:检查引用的类、字段和方法是否存在

 准备(Preparation)

为类变量分配内存并设置初始值:

  • 静态变量分配

    • 在方法区分配内存

    • 设置类型默认值(零值)

      • int → 0

      • boolean → false

      • 引用类型 → null

  • 特殊处理

    • static final 常量:直接赋程序指定值

// 准备阶段直接赋值
public static final int MAX = 100;

解析(Resolution)

将符号引用转换为直接引用:

  • 符号引用:用一组符号描述引用的目标

  • 直接引用:指向目标的指针、偏移量或句柄

初始化阶段

执行静态代码块的内容和给静态变量赋值,以字节码文件视角就是执行<clinit>方法

<clinit>() 方法特性

  1. 自动生成

    • 编译器收集所有类变量赋值静态代码块

    • 按源代码顺序合并生成

  2. 线程安全

    • JVM 保证只有一个线程执行初始化

    • 其他线程会阻塞等待完成

  3. 父类优先

    • 执行子类的 <clinit>() 前

    • 必须先执行父类的 <clinit>()

不会导致初始化

  1. 无静态代码块且无静态变量赋值语句。
  2. 有静态变量的声明,但是没有赋值语句。
  3. 静态变量的定义使用final关键字,这类变量会在准备阶段直接初始化 。
  4. 直接访问父类的静态变量,不会触发子类的初始化。
  5. 数组的创建不会导致数组中元素的类进行初始化。

初始化触发条件(严格规定)

  1. new 实例化对象

  2. 访问类的静态变量(非 final 常量)

  3. 调用类的静态方法

  4. 反射调用(Class.forName())

  5. 初始化子类时(父类需先初始化)

  6. JVM 启动时的主类

  7. MethodHandle 解析结果涉及静态方法

使用阶段

类的初始化之后,它就可以在程序中自由使用了。这包括创建实例、调用方法和访问字段等操作。在这个阶段,对象会被创建和操作,它们各自也会经历自己的生命周期。

卸载阶段

 在某些情况下,当一个类不再需要时,它会被卸载。类的卸载发生在垃圾收集的过程中,当确定某个类的Class对象不再被引用,且对应的ClassLoader实例也不再存在时,JVM就可能卸载这个类。但是,在常见的Java应用中,由于系统类加载器加载的类一直会被引用,所以这些类通常只有在JVM停止运行时才会被卸载。

面试题

说出一下代码的运行结果:

public class Demo01 {
    public static void main(String[] args) {
 
        System.out.println(B02.a);
    }
}
class A02
{
    static int a=0;
    static{
        System.out.println("A02");
        a=1;
    }
}
class B02 extends A02{
    static{
        System.out.println("B02");
        a=2;
    }
}

运行结果为A02 1  原因是因为:访问父类的静态变量,只初始化父类

public class Demo01 {
    public static void main(String[] args) {
        new B02();
        System.out.println(B02.a);
    }
}
class A02
{
    static int a=0;
    static{
        System.out.println("A02");
        a=1;
    }
}
class B02 extends A02{
    static{
        System.out.println("B02");
        a=2;
    }
}

首先执行main方法,new了B02所以要初始化它,但是它是子类,所以要先初始化A02,首先给赋值为0然后打印出A02,在给a赋值1,在初始化B02,打印出B02,a赋值为2,然后打印出a的值2

运行结果是:A02 B02 2

public class test5 {
    public static void main(String[] args) {
 
        System.out.println("A");
        new test5();
        new test5();
    }
    public  test5()
    {
        System.out.println("B");
    }
    {
        System.out.println("C");
    }
    static {
 
        System.out.println("D");
    }
 
}
  1. 先执行test5这个类的静态代码块输出D
  2. 在执行main方法打印A
  3. 在初始化test5,执行构造器方法和代码块方法,但是代码块先执行所以第一个new执行CB
  4. 第二个new执行CB
  5. 结果:DACBCB

以上面试题你都做对了吗?

总结

    Java类的生命周期包括:加载(将字节码加载到内存,生成Class对象)、连接(验证字节码、准备静态变量内存并赋默认值、解析符号引用)、初始化(执行静态代码块和赋值)、使用(创建实例、调用方法)、卸载(类不再使用时被回收)。按此顺序完成从加载到销毁的完整过程。

学习类的生命周期,能让我们对java语言有一个更深的认识,也能让我们在面试中多一点机会。

总之,类的生命周期从加载到卸载,经历了多个阶段,每个阶段都有特定的任务和目标。理解类的生命周期有助于我们更好地理解和管理Java程序的运行机制。

感谢你的阅读,希望文章能给你带来帮助,你的阅读点赞就是我最大的动力。

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

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

相关文章

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …

GitFlow 工作模式(详解)

今天再学项目的过程中遇到使用gitflow模式管理代码&#xff0c;因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存&#xff0c;无论是github还是gittee&#xff0c;都是一种基于git去保存代码的形式&#xff0c;这样保存代码…

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…

云原生安全实战:API网关Kong的鉴权与限流详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关&#xff08;API Gateway&#xff09; API网关是微服务架构中的核心组件&#xff0c;负责统一管理所有API的流量入口。它像一座…

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面&#xff0c;gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress&#xff0c;说明目标所使用的cms是wordpress&#xff0c;访问http://192.168.43.213/wordpress/然后查看源码能看到 这…

基于IDIG-GAN的小样本电机轴承故障诊断

目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) ​梯度归一化(Gradient Normalization)​​ (2) ​判别器梯度间隙正则化(Discriminator Gradient Gap Regularization)​​ (3) ​自注意力机制(Self-Attention)​​ 3. 完整损失函数 二…

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)

RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发&#xff0c;后来由Pivotal Software Inc.&#xff08;现为VMware子公司&#xff09;接管。RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;用 Erlang 语言编写。广泛应用于各种分布…

DingDing机器人群消息推送

文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人&#xff0c;点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置&#xff0c;详见说明文档 成功后&#xff0c;记录Webhook 2 API文档说明 点击设置说明 查看自…

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…

Selenium常用函数介绍

目录 一&#xff0c;元素定位 1.1 cssSeector 1.2 xpath 二&#xff0c;操作测试对象 三&#xff0c;窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四&#xff0c;弹窗 五&#xff0c;等待 六&#xff0c;导航 七&#xff0c;文件上传 …

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…

华为OD机考-机房布局

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…

如何更改默认 Crontab 编辑器 ?

在 Linux 领域中&#xff0c;crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用&#xff0c;用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益&#xff0c;允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…