【从零开始学习JVM | 第三篇】类的生命周期(高频面试)
前言:
在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。
在本文中,我们将深入探讨类的生命周期,从类加载到内存中的各个阶段,以及在这个过程中发生的一些关键事件和操作。我们将了解类的加载、链接和初始化过程,以及类在内存中的存储结构和引用方式。
目录
前言:
类的生命周期概述:
杂项知识点:
总结:
类的生命周期概述:
在Java中,类的生命周期较为复杂,涉及到加载、链接、初始化,使用和卸载几个主要阶段。下面详细解释这些阶段:
-
加载(Loading): 这是类的生命周期的第一个阶段。在这个阶段,Java虚拟机(JVM)将类的.class文件从硬盘读入内存,为之创建一个 java.long.class 对象,并且在方法区中生成一个 InstanceKlass 对象来存储类的基本信息。而开发者只能操作java.long.class 对象而不能操作InstanceKlass 对象 需要注意的是:静态字段的数据存储在java.long.class中。这两个对象是关联的,可以相互找到。类的加载通常是由类加载器完成的,包括引导类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和系统类加载器(System ClassLoader),还可以有用户自定义的类加载器。
-
链接(Linking): 加载完成后,类进入链接阶段,这个阶段又分为验证、准备和解析三个子阶段。
- 验证(Verification):确保被加载的类符合JVM规范,没有安全问题。
- 准备(Preparation):为类变量分配内存,并设置类变量的默认初始值 。并且需要注意的是:final修饰的基本数据类型的静态变量,准备阶段会直接将代码中的值进行赋值。
- 解析(Resolution):将类、接口、字段和方法的符号引用转换为直接引用。
-
初始化(Initialization): 链接阶段之后,类会被初始化。在这个阶段,JVM 负责执行类的静态初始化器和静态初始化块。这包括执行静态字段的赋值语句和静态代码块。初始化是在类首次被使用时触发的,例如实例化、访问静态字段或调用静态方法时。
-
使用(Using): 类的初始化之后,它就可以在程序中自由使用了。这包括创建实例、调用方法和访问字段等操作。在这个阶段,对象会被创建和操作,它们各自也会经历自己的生命周期。
-
卸载(Unloading): 在某些情况下,当一个类不再需要时,它会被卸载。类的卸载发生在垃圾收集的过程中,当确定某个类的
Class
对象不再被引用,且对应的ClassLoader实例也不再存在时,JVM就可能卸载这个类。但是,在常见的Java应用中,由于系统类加载器加载的类一直会被引用,所以这些类通常只有在JVM停止运行时才会被卸载。
需要注意的是,Java中的类卸载并不是很常见,因为大多数应用的生命周期内,其加载的类都会一直被使用。只有在某些特定的场景下,比如热部署、动态加载和卸载插件的应用服务器等环境中,类的卸载才是必要的。
杂项知识点:
1.类加载器的种类:
引导类加载器(Bootstrap ClassLoader):它是虚拟机的一部分,负责加载Java核心库(JAVA_HOME/jre/lib/rt.jar里面的类或-Xbootclasspath参数指定的路径中的类)。
扩展类加载器(Extension ClassLoader):它负责加载JAVA_HOME/jre/lib/ext目录中或java.ext.dirs系统属性指定路径中的类库。
系统类加载器(System ClassLoader):它根据Java应用的类路径(CLASSPATH)来加载Java应用类。
用户自定义加载器(User-Defined ClassLoaders):Java允许开发者通过继承java.lang.ClassLoader类的方式实现自己的类加载器。
2.什么是方法区:
方法区(Method Area)是Java虚拟机(JVM)中的一块内存区域,存储了已被加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。方法区不同于堆(Heap)和栈(Stack),它是线程共享的,存储的是类相关的数据而不是对象实例。
需要注意的是,Java 8及之前的版本中,方法区是位于永久代(Permanent Generation)内的。而从Java 8开始,永久代被元空间(Metaspace)取代,方法区的数据被存储在元空间中。元空间是使用堆内存来实现的,但是它与Java堆是独立分配和回收的,因此方法区并不属于堆或栈。
3.哪几种情况会导致类的初始化:
- 创建类的实例:当首次创建某个类的实例时,该类将被初始化。
- 访问类的静态方法:首次调用类的任意一个静态方法时,该类将被初始化。
- 访问类或接口的静态字段:首次访问类或接口的静态字段(除了常量字段)时,该类或接口将被初始化。
- 反射:使用反射方式调用Class.forName()时,如果指定了要进行初始化,则会触发类的初始化。
- 初始化子类:如果一个类还未被初始化,则在其任何子类被初始化时,该父类也会被初始化。
- Java虚拟机启动时:定义了main方法的那个类将在程序开始执行时被初始化。
- 动态语言支持:如果一个java.lang.invoke.MethodHandle实例最后的解析结果为REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且这个方法句柄对应的类没有进行过初始化,则需要先触发其初始化。
- 接口的默认方法:如果接口定义了默认方法,并且在首次调用其实现类的任何默认方法时,该接口会被初始化。
- 子类的初始化clinit调用之前,会先调用父类的clinit初始化方法。
4.哪几种方式不会导致类的初始化
- 无静态代码块且无静态变量赋值语句。
- 有静态变量的声明,但是没有赋值语句。
- 静态变量的定义使用final关键字,这类变量会在准备阶段直接初始化 。
- 直接访问父类的静态变量,不会触发子类的初始化。
- 数组的创建不会导致数组中元素的类进行初始化。
面试题实战:
说出以下代码运行结果:
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");}}
- 首先,在类加载过程中,会执行静态代码块中的代码。因此,静态代码块中的输出语句System.out.println("D");会被执行一次,打印出"D"。
- 接着,在main方法中,首先输出字符"A"。
- 然后创建了第一个test5对象。在创建对象时,首先会执行实例代码块中的代码。因此,实例代码块中的输出语句System.out.println("C");会被执行一次,打印出"C"。接着,执行构造方法test5()中的代码,打印出"B"。
- 再创建第二个test5对象时,同样会执行实例代码块中的代码,打印出"C"。接着,执行构造方法test5()中的代码,打印出"B"。。
因此打印结果为DACBCB,你做对了吗?
说出以下运行结果:
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方法,在main方法中创建了一个B02对象,由于B02继承自A02,因此会先初始化A02类。在A02类的静态代码块中,会输出"A02"并将a的值赋为1。接着初始化B02类,在B02类的静态代码块中,会输出"B02"并将a的值赋为2。最后,打印输出B02.a的值,即为2。
因此打印结果为:A02 B02 2,你做对了吗?
说出以下结果:
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 原因是因为:访问父类的静态变量,只初始化父类。
总结:
类的生命周期从加载、验证、准备、解析到初始化,每个阶段都有特定的任务和目标。在加载阶段,类的字节码数据被加载到内存中,并存储在方法区中。验证阶段验证类的字节码的正确性和安全性。准备阶段为静态变量分配内存并设置默认初始值,也将静态变量存储在方法区中。解析阶段将符号引用解析为直接引用,以便后续的方法调用。最后,在初始化阶段初始化类的静态变量和执行静态代码块的逻辑。
通过了初始化阶段的类可以进入正常的使用阶段,在这个阶段中,类的实例可以被创建,实例变量和方法可以被调用。但是,我们也要意识到类的生命周期并不只局限于这些阶段。类的卸载是一个不确定的阶段,只有当类的加载器认为它不再需要时,类才会被卸载。此外,类的生命周期还受到一些因素的影响,例如类的引用是否存在,是否被其他对象引用等。
了解类的生命周期对于理解Java程序的运行机制非常重要。它帮助我们理解类的加载、初始化和使用过程,并在必要时进行优化和资源管理。同时,深入了解类的生命周期也有助于我们编写更高效、可靠的Java应用程序。
总之,类的生命周期从加载到卸载,经历了多个阶段,每个阶段都有特定的任务和目标。理解类的生命周期有助于我们更好地理解和管理Java程序的运行机制。
如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力!
相关文章:
【从零开始学习JVM | 第三篇】类的生命周期(高频面试)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。 在本文中,我们将深入探讨类的生命周期,从类加载到…...
详解前后端交互时PO,DTO,VO模型类的应用场景
前后端交互时的数据传输模型 前后端交互流程 前后端交互的流程: 前端与后端开发人员之间主要依据接口进行开发 前端通过Http协议请求后端服务提供的接口后端服务的控制层Controller接收前端的请求Contorller层调用Service层进行业务处理Service层调用Dao持久层对数据持久化 …...
力扣295. 数据流的中位数
优先队列 思路: 中位数是排序中间的数值:S1.M.S2可以使用两个优先队列来存放两边的数值,总是使得左侧的堆顶是最大的,右侧的堆顶是最小的,即使用大顶堆存放 S1,使用小顶堆存放S2,使得两个队列的…...
英语二笔记
完型填空 20题/0.5分 总分10, 至少拿8分 阅读理解A 20题/2分 总分40 至少拿24分 阅读理解B 5题/2分 总分10 至少拿6分 短文翻译 1题/15分 …...
【OpenSSH升级】升级后证书认证登录突然失效
上一篇“【OpenSSH升级】无论密码输入正确与否总是登录失败(error: Could not get shadow information for root)”总结了CentOS7上的openssh从7.4升级到9.4之后,密码认证失败问题,这里再总结一下证书认证失效问题。 大多数情况下…...
pytest +uiautomator2+weditor app自动化从零开始
目录结构1.0 把设备连接单独移出去了 模块操作代码,有一些流程操作和断言方法 from devices import dv from time import sleep import random from tool.jt import capture_screenshotdef initialization(func):def wrapper():sleep(1)dv.app_stop(com.visteon.…...
【计算机网络笔记】物理层——信道与信道容量
系列文章目录 什么是计算机网络? 什么是网络协议? 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能(1)——速率、带宽、延迟 计算机网络性能(2)…...
深度学习火车票识别系统 计算机竞赛
文章目录 0 前言1 课题意义课题难点: 2 实现方法2.1 图像预处理2.2 字符分割2.3 字符识别部分实现代码 3 实现效果4 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 图像识别 火车票识别系统 该项目较为新颖,适…...
C++EasyX之井字棋
视频链接 井字棋 用EasyX和C实现井字棋小游戏 源码及注释 #include<graphics.h>char board_data[3][3] {{-,-,-},{-,-,-},{-,-,-}, };char current_piece O;//检测指定棋子的玩家是否获胜 bool CheckWin(char c) {// 检查每一行for (int i 0; i < 3; i){if (bo…...
12.5_黑马数据结构与算法Java
目录 001 二分查找 算法描述 002 二分查找 算法实现 003 二分查找 问题1 循环条件 004 二分查找 问题2 中间索引 thinking:反码补码原码? thinking:二进制转十进制? thinking:无符号右移? 005 二分…...
【PID学习笔记 5 】控制系统的性能指标之一
写在前面 PID在实际工程中最重要的工作就是调参,那么首先就要了解控制系统的性能指标。上文最后简要介绍了控制系统的基本要求,本文开始将系统学习控制系统的性能指标,内容比较多,初步计划是分三节来讲解。本文重点介绍性能指标的…...
HarmonyOS学习--TypeScript语言学习(三)
本章目录如下 一、条件语句 二、迭代器 三、循环 四、函数 五、类 一、条件语句 条件语句用于基于不同的条件来执行不同的动作。TypeScript 条件语句是通过一条或多条语句的执行结果(True 或 False)来决定执行的代码块。 在 TypeScript 中&#x…...
Matlab 镜像变换(2D)
文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 镜像变换是一个非常有趣的过程,它有着一个通用的套路(以2D为例):一个点围绕一个给定对称轴的镜像可以通过平移对称轴上一点,然后旋转它,使对称轴与x轴对齐,之后我们将旋转后的点的y坐标置为负,最后再将对称…...
SpringBoot3-快速体验
1、pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.…...
计数问题(数位DP)
题目大意:给定一个区间,求该区间内0 ~ 9出现的次数,多次询问,以0 0结束询问 测试用例: 输入: 1 10 44 497 346 542 1199 1748 1496 1403 1004 503 1714 190 1317 854 1976 494 1001 1960 0 0 输出ÿ…...
SQL Server事务(Transaction)
5. 事务(Transaction) 5.1. 事务概念 事务是关系库中不可分割的一系列数据库操作,这些操作必须要么整体成功,要么整体失败。事务维护数据完整性,保证数据库总是处于一致性状态。虽然,各关系库中事务实现和操作的具体细节有所不同,但基本概念和功能完全相同,而具体操作…...
Python语言基础学习大纲(由某大模型生成)
自从上次经丙察察游了一次滇藏线,已有3个没写一篇了。今天利用由某大模型生成的上面这张思维导图,配合这个大模型生成的6000多字拼凑出一篇博文聊以交差。 Python语言概述 一、语言特点 1.语法简单明了 Python的语法简洁易懂,使得编写代码…...
nodejs+vue+微信小程序+python+PHP天天网站书城管理系统的设计与实现-计算机毕业设计推荐
本项目主要分为前台模块与后台模块2个部分,详细描述如下: (1)前台模块 首页: 首页可以起到导航的作用,用户想要了解网站 ,网站首页为用户可以深入了解网站提供了一个平台,它就向一个“导游”…...
工业机器视觉megauging(向光有光)使用说明书(十二,轻量级的visionpro)
关于最后一个工具的介绍:就是这个“相机图像” 我们可以鼠标双击点进去看一看: 在图像上点击,就可以截取一块图像,是可以放大缩小的,这个放大很low,是我以前研究缩放入门时的版本,本想删除&…...
HarmonyOS学习--了解基本工程目录
1.工程级目录 工程的目录结构如下: 其中详细如下: AppScope中存放应用全局所需要的资源文件。entry是应用的主模块,存放HarmonyOS应用的代码、资源等。oh_modules是工程的依赖包,存放工程依赖的源文件。build-profile.json5是工…...
JRT导出协议实现
之前实现了JRT的打印客户端实现,这次实现JRT的导出Excel的客户端实现,这样这套框架就成为完全体了。还是一样的设计,不面向具体业务编程,我喜欢面向协议编程,导出一样定义了一套协议。 协议约定: 然后就是…...
Unity中动态合批
文章目录 前言一、动态合批的规则1、材质相同是合批的前提,但是如果是材质实例的话,则一样无法合批。2、支持不同网格的合批3、动态合批需要网格支持的顶点条件二、我们导入一个模型并且制作一个Shader,来测试动态合批1、我们选择模型的 Mesh…...
逆水行舟!浅谈24届双非本科秋招
逆水行舟!浅谈24届双非本科的秋招 逆水行舟!浅谈24届双非本科的秋招0、背景 -- 写下本文的初衷1、实习 -- 秋招的预备战役1.1 科大讯飞1.2 三七互娱 2、秋招 -- 一场没有硝烟的战争3、总结 -- 做好自己想做的事情 0、背景 – 写下本文的初衷 如题&#…...
vue3请求代理proxy中pathRewrite失效
问题引入 在vue3配置请求代理proxy的时候pathRewrite失效。 有这样一个例子,作用是为了把所有以/api开头的请求代理到后端的路径和端口上,在vue.config.js配置文件中 设置了代理跨域和默认端口。但是重新运行之后发现端口是改了,但是路径仍然…...
练习题——-【学习补档】日期差值
问题描述 描述 有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定他们之间的天数为两天。 输入描述: 有多组数据,每组数据有两行,分别表示两个日期,形式为YYYYMMDD 输出描述: 每组…...
面试问题 --文件描述符和流
文件描述符概述 文件描述符是计算机操作系统中用于标识和访问文件或输入/输出设备的抽象概念。在Unix和类Unix系统中,文件描述符是一个非负整数,用于唯一标识打开的文件或I/O设备。本文将介绍文件描述符的基本概念和在Unix环境中的应用。 基本概念 文…...
离线安装Zabbix的MariaDB报Error: Package: 1:mariadb-server-5.5.68-1.el7.x86 64异常解决方法
离线安装Zabbix,结果在安装MariaDB时候,报出以下异常 Error: Package: 1:mariadb-server-5.5.68-1.el7.x86 64(New) Requires: per(File::Path) Error: Package: perl-IO-Compress-2.061-2.el7.noarch (New) Requires: perl(I0: :Seekable) Error: Pack…...
【go语言开发】go项目打包成Docker镜像,包括Dockerfile命令介绍、goctl工具生成
本文主要介绍如何将go项目打包成镜像,首先介绍Dockerfile常用命令介绍,然后介绍使用工具goctl用于生成Dockerfile,还可以根据需求自定义指令内容,最后讲解如何将go-blog项目打包成镜像,以及如何运行等 文章目录 前言Do…...
Python:可以做什么?
简介 Python是一种高级编程语言,因其简单易学、代码可读性强和拥有丰富的标准库而广受欢迎。Python可以用于许多不同领域,主要包括: 数据分析与数据科学:Python有强大的数据处理和分析库,如Pandas、NumPy和SciPy&…...
Lookup Argument简史
1. 引言 主要参考Ingonyama团队2023年4月文章《A Brief History of Lookup Arguments》。 近年来zk-SNARKs的研究热点有: 让ZKP proof更succinct降低Prover time和Verifier time 但,大多数SNARKs仍受限于,易于转换为多项式的算术运算。通…...
全球最好的黄页网站/域名解析ip
如果对您有帮助,请点赞告诉我,如果没有解决您的疑惑,请您留言,我陪您一起努力解决!这里只介绍常用的一些概念,一些极少用到的概念为避免混淆这里不做介绍。 简单的来说,BLE的服务端属性数据库可…...
重庆网站建设解决方案/网络优化的三个方法
我的新书《Android App开发入门与实战》已于2020年8月由人民邮电出版社出版,欢迎购买。点击进入详情 文章目录如果你最近在使用git命令,你会发现输入github的账号密码会报错。比如:git push origin master当你输入github的帐号密码后…...
php怎么做全网小视频网站/seo必备软件
实验步骤一 generate()方法,生成字符串,要求字符串为“haihai”或者“world!”,如下: getone()方法生成随机的四、六位数,这个方法只会生成一个结果。如果使用的是generate()方法,那么会列出所有的可能。随机生成一个时间实验步骤二 # -*- coding: utf-8 -*- #大小写ZH…...
手机网站设计机构/google入口
2020年注定是个不平凡的一年,疫情的影响下,全世界都在遭受疫情的冲击。在这种大环境下,晋陶机械的创始人---陶正勇,并不是坐以待毙,相反,他潜心研究、创新突破自己产业的瓶颈。顺应市场需求,助力…...
一些可以做翻译的网站/seo外包网络公司
源码获取:博客首页 "资源" 里下载! 项目介绍 CRM人事管理系统,主要功能有: 用户管理:用户查询、添加用户、编辑、删除; 职位管理:职位查询、添加职位、删除; 部门管理&am…...
一般做外单的有哪些网站/315影视行业
1. 卷积神经网络结构 卷积神经网络是一个多层的神经网络,每层都是一个变换(映射),常用卷积convention变换和pooling池化变换,每种变换都是对输入数据的一种处理,是输入特征的另一种特征表达;每层…...