深入理解java虚拟机(七)类加载的时机
Class 文件中描述的各种信息都必须加载到虚拟机中才能运行和使用。而虚拟机怎么加载这些Class 文件呢?Class 文件进入到虚拟机中会发生什么变化呢?
虚拟机类加载机制是指 虚拟机把描述类的数据从 Class 文件加载到内存中,并对数据进行校验、转换解析、初始化,最终形成可以被虚拟机直接使用的Java 类型。
与那些在编译器进行连接工作的语言不同,Java 中,类的加载一直到初始化过程都是在运行期间完成的,虽然会损失一点性能,但是却使Java 应用程序具有高度灵活的特性。Java 可以动态扩展的特性就是依赖于运行期动态加载和动态连接这个特点实现的。
类加载的时机
类从被加载到虚拟机内存开始,到卸载出内存为止,它的整个生命周期包括:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)7个阶段。其中,验证、准备和解析统称为连接(Linking)。过程如下图所示。
图1 类的生命周期
上述七个过程,除了解析(Resoluton)阶段外,其余的六个过程都必须按部就班的“开始”,之间可能有部分相互交叉的混合执行。 解析过程在某些情况下,可以在初始化阶段之后再开始,这也是为了支持Java 语言的运行时绑定(也称为动态绑定或晚期绑定)。
Java虚拟机规范并没有规定什么时候需要进行类的加载阶段,但是却规定5中情况必须对类进行初始化。
- 实例化对象、读写类静态字段、调用静态方法的时候
- 使用反射调用的时候
- 初始化类时,需要先触发父类的初始化
- 虚拟机启动时,会先初始化包含 main() 方法的主类
- 使用JDK1.7 的动态语言支持的时候,如果 java.lang.invoke.MethodHandle 实例最后的解析结果REF_getStatic 、REF_putStatic、REF_invokeStatic的方法句柄,句柄对应的类会被初始化
被动引用
- 通过子类引用父类中定义的静态字段,只会触发父类的初始化。至于是否会触发子类的加载和验证,取决于虚拟机的具体实现(HotSpot不会加载)。
- 通过数组定义来引用类,如 A[] ints = new A[10] , 不会触发A 类的初始化。而是会会触发名为 LA的类初始化。它是一个由虚拟机自动生成的、直接继承于Object 的子类,创建动作由字节码指令 newarray 触发。这个类代表了一个元素类型为 A 的一位数组,数组中的属性和方法都实现在这个类中。Java 语言中数组的访问比C/C++ 安全是因为这个类封装了数组元素的访问方法。
- 常量在编译阶段会存入调用类的常量池中,本质上并没有直接引用到定义常量的类,因此不会触发定义常量的类的初始化。
- package xiaoye.java;
- class Constant{
- static {
- System.out.print("ConstantClass inited!");
- }
- public static final String HELLOWORLD = "hehe";
- }
- public class ConstantClass {
- public static void main(String[] args){
- System.out.print(Constant.HELLOWORLD);
- }
- }
接口加载的时机
深入理解java虚拟机(七)类加载的时机的更多相关文章
- 深入理解Java虚拟机(类加载机制)
文章首发于微信公众号:BaronTalk 上一篇文章我们介绍了「类文件结构」,这一篇我们来看看虚拟机是如何加载类的. 我们的源代码经过编译器编译成字节码之后,最终都需要加载到虚拟机之后才能运行.虚拟机 ...
- 深入理解java虚拟机【类加载机制】
Java虚拟机类加载过程是把Class类文件加载到内存,并对Class文件中的数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的java类型的过程. 在加载阶段,java虚拟机需要完成以下 ...
- 深入理解java虚拟机(三)-----类加载机制
类加载机制jvm把描述类的数据从class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被jvm直接使用的java类型.在java中,类型的加载.连接和初始化都是在程序运行期间完成的 ...
- 深入理解Java虚拟机(八)——类加载机制
是什么是类加载机制 Java虚拟机将class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这个过程就是类加载机制. 类的生命周期 一个类从加载到内存 ...
- 【进阶之路】深入理解Java虚拟机的类加载机制(长文)
我们在参加面试的时候,经常被问到一些关于类加载机制的问题,也都会在面试之前准备的时候背好答案,但是我们是否有去深入了解什么是类加载机制呢?这段时间因为一些事情在家看了些书,这次就和大家分享一些关于Ja ...
- 深入理解java虚拟机(4)类加载的过程
类加载的过程 ------------------------------------------------------- 0.如下图所示JVM类加载机制分为5个部分:加载.验证.准备.解析.初始化 ...
- 深入理解Java虚拟机之类加载机制篇
概述 虚拟机把描述类的数据从 Class 文件加载到内存中,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,就是虚拟机的类加载机制. 在Java语言里面,类型的 ...
- 深入理解Java虚拟机(七)——类文件结构
Java的无关性 由于计算机领域中有很多操作系统和硬件平台同时在竞争,所以,很多编程语言的程序设计会与其运行的平台和操作系统产生耦合,这样就大大增加了程序员的工作,为了适应不同的平台,需要修改很多代码 ...
- 深入理解java虚拟机,类加载
1,通过使用静态字段,只有真正定义这个字段的类才会被初始化,(子类不初始化,父类初始化 2,new数组,不初始化 3,通过类来调用一些类的常量,可以不初始化类,(常量在编译期,被优化到NotIniti ...
- 【深入理解Java虚拟机 】类加载器的命名空间以及类的卸载
类加载器的命名空间 每个类加载器又有一个命名空间,由其以及其父加载器组成 类加载器的命名空间的作用和影响 每个类加载器又有一个命名空间,由其以及其父加载器组成 在每个类加载器自己的命名空间中不能出现相 ...
随机推荐
- 【CVE】CVE-2018-4304 Apple多个操作系统函数拒绝服务漏洞
TextImpact: Processing a maliciously crafted text file may lead to adenial of serviceDescription: A ...
- OD 实验(一) - 修改程序标题
需要修改的程序 把 I love fishc.com 修改为 hello world sch01ar 用 OD 打开程序 在程序入口处开始一直按 F8 运行程序,看看在哪里弹出对话框 运行到该地址的时 ...
- Netty面试题
1.BIO.NIO和AIO的区别? BIO:一个连接一个线程,客户端有连接请求时服务器端就需要启动一个线程进行处理.线程开销大. 伪异步IO:将请求连接放入线程池,一对多,但线程还是很宝贵的资源. N ...
- 无法添加数据连接。Could not load file or assembly 'Microsoft.SqlServer.Management.Sdk.Sfc, Version=11.0.0.0
无法添加数据连接.Could not load file or assembly 'Microsoft.SqlServer.Management.Sdk.Sfc, Version=11.0.0.0 V ...
- C#接口的三种实现方式
转自原文C#接口的三种实现方式 public interface MyInterface { /// 下面三个方法的签名都是 /// .method public hidebysig newslot ...
- 用C#操作IO端口1-用并口控制发光二极管
什么是端口? 端口包含了一系列信号线, 通过这个端口CPU可以同其他外部设备交换数据, 比如我们经常见到的Modem,打印机等. 通常情况下, 打开的信号是”1”, 关闭的信号是”0”. 并口在同一时 ...
- 微信小程序中this关键字使用技巧
转自:https://blog.csdn.net/qq_33956478/article/details/81348453 微信小程序中,在wx.request({});方法调用成功或者失败之后,有时 ...
- FilreDAC DLL共享数据连接
D:\Users\Public\Documents\Embarcadero\Studio\16.0\Samples\Object Pascal\Database\FireDAC\Samples\Com ...
- C# unsafe模式内存操作深入探索
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Run ...
- shell脚本里切换用户执行命令的注意事项
功能说明:用root用户执行一个脚本,脚本里需要切换到普通用户DT去执行其他命令,其中就用到了EOF,用法如下: #!/bin/bash su - DT<<EOF cd apache-to ...