JVM——类的生命周期
文章目录
- 类加载过程
- 加载
- 验证
- 准备
- 解析
- 初始化
- 卸载
一个类的完整生命周期如下:
类加载过程
Class 文件需要加载到虚拟机中之后才能运行和使用,那么虚拟机是如何加载这些 Class 文件呢?
系统加载 Class 类型的文件主要三步:加载->连接->初始化。连接过程又可分为三步:验证->准备->解析。
加载
类加载过程的第一步,主要完成下面3件事情:
- 通过全类名获取定义此类的二进制字节流
- 将字节流所代表的静态存储结构转换为方法区的运行时数据结构
- 在内存中生成一个代表该类的 Class 对象,作为方法区这些数据的访问入口
虚拟机规范上面这3点并不具体,因此是非常灵活的。比如:“通过全类名获取定义此类的二进制字节流” 并没有指明具体从哪里获取、怎样获取。比如:比较常见的就是从 ZIP 包中读取(日后出现的JAR、EAR、WAR格式的基础)、其他文件生成(典型应用就是JSP)等等。
一个非数组类的加载阶段(加载阶段获取类的二进制字节流的动作)是可控性最强的阶段,这一步我们可以去完成还可以自定义类加载器去控制字节流的获取方式(重写一个类加载器的 loadClass()
方法)。数组类型不通过类加载器创建,它由 Java 虚拟机直接创建。
类加载器、双亲委派模型也是非常重要的知识点,这部分内容会在后面的文章中单独介绍到。
加载阶段和连接阶段的部分内容是交叉进行的,加载阶段尚未结束,连接阶段可能就已经开始了。
验证
准备
准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些内存都将在方法区中分配。对于该阶段有以下几点需要注意:
- 这时候进行内存分配的仅包括类变量(static),而不包括实例变量,实例变量会在对象实例化时随着对象一块分配在 Java 堆中。
- 这里所设置的初始值"通常情况"下是数据类型默认的零值(如0、0L、null、false等),比如我们定义了
public static int value=111
,那么 value 变量在准备阶段的初始值就是 0 而不是111(初始化阶段才会赋值)。特殊情况:比如给 value 变量加上了 fianl 关键字public static final int value=111
,那么准备阶段 value 的值就被赋值为 111。
基本数据类型的零值:
解析
解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用限定符7类符号引用进行。
符号引用就是一组符号来描述目标,可以是任何字面量。直接引用就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄。在程序实际运行时,只有符号引用是不够的,举个例子:在程序执行方法时,系统需要明确知道这个方法所在的位置。Java 虚拟机为每个类都准备了一张方法表来存放类中所有的方法。当需要调用一个类的方法的时候,只要知道这个方法在方发表中的偏移量就可以直接调用该方法了。通过解析操作符号引用就可以直接转变为目标方法在类中方法表的位置,从而使得方法可以被调用。
综上,解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程,也就是得到类或者字段、方法在内存中的指针或者偏移量。
初始化
初始化是类加载的最后一步,也是真正执行类中定义的 Java 程序代码(字节码),初始化阶段是执行初始化方法 <clinit> ()
方法的过程。
对于<clinit>()
方法的调用,虚拟机会自己确保其在多线程环境中的安全性。因为 <clinit>()
方法是带锁线程安全,所以在多线程环境下进行类初始化的话可能会引起死锁,并且这种死锁很难被发现。
对于初始化阶段,虚拟机严格规范了有且只有5种情况下,必须对类进行初始化(只有主动去使用类才会初始化类):
- 当遇到 new 、 getstatic、putstatic或invokestatic 这4条直接码指令时,比如 new 一个类,读取一个静态字段(未被 final 修饰)、或调用一个类的静态方法时。
- 当jvm执行new指令时会初始化类。即当程序创建一个类的实例对象。
- 当jvm执行getstatic指令时会初始化类。即程序访问类的静态变量(不是静态常量,常量会被加载到运行时常量池)。
- 当jvm执行putstatic指令时会初始化类。即程序给类的静态变量赋值。
- 当jvm执行invokestatic指令时会初始化类。即程序调用类的静态方法。
- 使用
java.lang.reflect
包的方法对类进行反射调用时如Class.forname(“…”),newInstance()等等。 ,如果类没初始化,需要触发其初始化。 - 初始化一个类,如果其父类还未初始化,则先触发该父类的初始化。
- 当虚拟机启动时,用户需要定义一个要执行的主类 (包含 main 方法的那个类),虚拟机会先初始化这个类。
- MethodHandle和VarHandle可以看作是轻量级的反射调用机制,而要想使用这2个调用,
就必须先使用findStaticVarHandle来初始化要调用的类。 - 「补充,来自issue745」 当一个接口中定义了JDK8新加入的默认方法(被default关键字修饰的接口方法)时,如果有这个接口的实现类发生了初始化,那该接口要在其之前被初始化。
卸载
卸载这部分内容来自 issue#662由 guang19 补充完善。
卸载类即该类的Class对象被GC。
卸载类需要满足3个要求:
- 该类的所有的实例对象都已被GC,也就是说堆不存在该类的实例对象。
- 该类没有在其他任何地方被引用
- 该类的类加载器的实例已被GC
所以,在JVM生命周期类,由jvm自带的类加载器加载的类是不会被卸载的。但是由我们自定义的类加载器加载的类是可能被卸载的。
只要想通一点就好了,jdk自带的BootstrapClassLoader,ExtClassLoader,AppClassLoader负责加载jdk提供的类,所以它们(类加载器的实例)肯定不会被回收。而我们自定义的类加载器的实例是可以被回收的,所以使用我们自定义加载器加载的类是可以被卸载掉的。
相关文章:

JVM——类的生命周期
文章目录 类加载过程加载验证准备解析初始化 卸载 一个类的完整生命周期如下: 类加载过程 Class 文件需要加载到虚拟机中之后才能运行和使用,那么虚拟机是如何加载这些 Class 文件呢? 系统加载 Class 类型的文件主要三步:加载->连接->…...
【Docker】docker数据卷(数据挂载)持久化
docker数据卷(数据挂载)持久化 一、docker对于数据的管理二、docker挂载主机目录---指定路径挂载三、docker使用数据卷Volume挂载四、数据共享--数据卷容器五、备份和恢复 docker的镜像是由多个只读的文件系统叠加在一起形成的。当我们在我启动一个容器的…...

Spring Boot实现IP地址解析
一、本地解析 如果使用本地ip解析的话,我们将会借助ip2region,该项目维护了一份较为详细的本地ip地址对应表,如果为了离线环境的使用,需要导入该项目依赖,并指定版本,不同版本的方法可能存在差异。 <d…...

小程序中通过canvas生成并保存图片
1. html <canvas class"canvas" id"photo" type"2d" style"width:200px;height: 300px;"></canvas> <button bindtap"saveImage">保存</button> <!-- 用来展示生成的那张图片 --> <image…...

Error creating bean with name ‘esUtils‘ defined in file
报错异常: 背景: esUtils在common服务中、启动media服务时候、报这个异常、后排查esUtils在启动时候发生异常引起的、在相关bean中加入try{}catch{}即可解决问题 String[] split url.split(","); HttpHost[] httpHosts new HttpHost[split.…...

Java开发面试题 | 2023
Java基础 接口和抽象类的区别?Java动态代理HashMap 底层实现及put元素的具体过程currenthashmap底层实现原理?map可以放null值吗,currenthashmap为什么不能放null值synchronze和reetrantlock区别?怎样停止一个运行中的线程&#…...

Java课题笔记~ 自定义拦截器实现权限验证
实现一个权限验证拦截器。 1、修改web.xml文件中请求路径 2、将所有的页面放入WEB-INF目录下 3、开发登录FirstController 4、开发拦截器 5、配置springmvc.xml文件 <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.spri…...

微信小程序使用npm引入三方包详解
目录 1 前言2 微信小程序npm环境搭建2.1 创建package.json文件2.2 修改 project.config.json2.3 修改project.private.config.json配置2.4 构建 npm 包2.5 typescript 支持2.6 安装组件2.7 引入使用组件 1 前言 从小程序基础库版本 2.2.1 或以上、及开发者工具 1.02.1808300 或…...

pytest自动化框架运行全局配置文件pytest.ini
还记得在之前的篇章中有讲到Pytest是目前主要流行的自动化框架之一,他有基础的脚本编码规则以及两种运行方式。 pytest的基础编码规则是可以进行修改,这就是今日文章重点。 看到这大家心中是否提出了两个问题:pytest的基础编码规则在哪可以…...

视频播放实现示例Demo
学习链接 vuespringboot文件分片上传与边放边播实现 同步加载、播放视频的实现 ---- range blob mediaSource 通过调试技术,我理清了 b 站视频播放很快的原理 MSE (Media Source Extensions) 上手指南 浅聊音视频的媒体扩展(Media Source Extension…...
makefile的自动化变量
一、是什么? 自动化变量:makefile依据执行的规则自动变化生成的变量 $(@) 规则的目标文件名 $(^) 所有依赖 依赖列表 $(<)第一个依赖文件名 $(*)规则中目标中%部分名 $(?)所有比目标文件更新的依赖文件列表,空格分隔 二、使用步骤 1.引入库 代码如下(示例): make …...

使用Kind搭建本地k8s集群环境
目录 1.前提条件 2.安装Kind 3.使用Kind创建一个K8s集群 3.1.创建一个双节点集群(一个Master节点,一个Worker节点) 3.2.验证一下新创建的集群信息 3.3.删除刚刚新建的集群 4.安装集群客户端 4.1.安装kubectl 4.1.1.验证kubectl 4.2.安…...

【STM32RT-Thread零基础入门】 7. 线程创建应用(多线程运行机制)
硬件:STM32F103ZET6、ST-LINK、usb转串口工具、4个LED灯、1个蜂鸣器、4个1k电阻、2个按键、面包板、杜邦线 文章目录 前言一、RT-Thread相关接口函数1. 获取当前运行的线程2. 设置调度器钩子函数 二、程序设计1. 头文件包含及宏定义2. 线程入口函数定义3. main函数设…...
.net日志系统
.NET 平台提供了强大的日志记录系统,用于在应用程序中记录各种事件、错误和调试信息。最常用的日志记录库是 Microsoft.Extensions.Logging,它是一个通用的日志接口和基础框架,可以与多种日志实现集成。以下是如何使用 .NET 日志系统的基本步骤: 安装 NuGet 包:首先,您需…...

SpringCloud学习笔记(二)_Eureka注册中心
一、Eureka简介 Eureka是一项基于REST(代表性状态转移)的服务,主要在AWS云中用于定位服务,以实现负载均衡和中间层服务器的故障转移。我们称此服务为Eureka Server。Eureka还带有一个基于Java的客户端组件Eureka Clientÿ…...
spark的eventLog日志分析
查找满足指定条件的app_id查询条件: 表名、时间、节点名时间限定: 最好适当放大, 不知道什么原因有点不准eventLog的存放路径: spark.history.fs.logDirectory 1. spark-sql 先限定时间段;数据是逐行读入的, 但 app_id要按整个文件过滤, 按每个条件打标;按app_id粒度聚合, 查…...

探究Java spring中jdk代理和cglib代理!
面对新鲜事物,我们要先了解在去探索事物的本质-默 目录 一.介绍二者代理模式 1.1.Jdk代理模式 1.2cglib代理模式 1.3二者区别 1.3.1有无接口 1.3.2灵活性 1.4对于两种代理模式的总结 1.4.1jdk代理模式 1.4.2cglib代理模式 二.两种代理模式应用场景 2.1jd…...
反转链表(C++)
1、迭代法的一种写法 ListNode* reverse_linkList(ListNode* head){if(head nullptr || head->next nullptr) return head;ListNode* begin nullptr;ListNode* mid head;ListNode* end head->next;while(true){mid->next begin;if(end nullptr){break;}begin …...
适配器模式:让不兼容的接口协同工作
在面向对象设计中,适配器模式是一种常见的结构型设计模式。它允许将不兼容的接口转换成客户端所期望的另一个接口,从而使不同的类协同工作。适配器模式的主要目的是解决不同接口之间的兼容性问题,同时也提高了代码的可重用性和灵活性。 问题…...
【1day】复现Milesight-VPNserver.js 任意文件读取漏洞
目录 一、漏洞描述 二、影响版本 三、资产测绘 四、漏洞复现 一、漏洞描述 Milesight路由器-VPN是由Milesight Technology Co., Ltd.开发的一种集成了VPN功能的路由器产品。它旨在为用户提供安全、可靠的远程访问和连接解决方案。Milesight-VPNserver.js存在任意文件读取…...

XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...

基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...

R 语言科研绘图第 55 期 --- 网络图-聚类
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...

【Veristand】Veristand环境安装教程-Linux RT / Windows
首先声明,此教程是针对Simulink编译模型并导入Veristand中编写的,同时需要注意的是老用户编译可能用的是Veristand Model Framework,那个是历史版本,且NI不会再维护,新版本编译支持为VeriStand Model Generation Suppo…...