JVM系列(一):JVM类加载过程详解
Java 通过引入字节码和 JVM 机制,提供了强大的跨平台能力,理解 Java 的类加载机制是深入 Java 开发的必要条件。
一、Java代码执行流程
Java程序运行时,必须经过编译和运行两个步骤。首先将后缀名为.java的源文件进行编译,最终生成后缀名为.class的字节码文件。然后JVM虚拟机启动时,会初始化好类加载器(ClassLoader)。通过ClassLoader,JVM将编译好的字节码文件加载到内存(类加载)。最后由JVM对加载到内存的java类进行解释执行,显示结果。
以我们常见的Test.java为例,具体流程如下图所示:
二、类加载过程
类加载过程主要分为三个步骤:加载、链接、初始化,而其中链接过程又分为三个步骤:验证、准备、解析,加上卸载、使用两个步骤统称为为类的生命周期。
加载
简单来说,加载指的是把class字节码文件从各个来源通过类加载器装载入内存中。
1、字节码来源
由于没有具体指明需要在哪里获取class文件,导致字节码来源途径非常丰富:
从压缩包中读取,如jar、war
从网络中获取,如Web Applet
动态生成,如动态代理、CGLIB
由其他文件生成,如JSP
从数据库读取
从加密文件中读取
2、内存储存
将静态储存解析成运行时数据,存放在方法区
在堆区生成该类的Class对象,作为方法区这个类的各种数据的访问入口。
链接
验证
验证阶段主要是为了为了确保Class文件的字节流中包含的信息符合虚拟机要求,并且不会危害虚拟机。
而验证主要分为以下四类:
文件格式验证
元数据验证
字节码验证
符号引用验证
准备
准备阶段会为类的静态变量分配内存、赋初值
数据类型 | 零值 |
---|---|
int | 0 |
long | 0L |
short | (short)0 |
char | ‘\u0000’ |
byte | (byte)0 |
boolean | false |
float | 0.0f |
double | 0.0d |
reference | null |
需要注意的有以下几点:
- 实例变量是在创建对象的时候完成赋值的,没有赋初值一说
- final修饰的常量在编译的时候会给属性添加ConstantValue属性,准备阶段直接完成赋值,即没有赋初值这一步
解析
解析阶段会将符号引用替换为直接引用,该过程也被称为静态链接。
1、符号引用
以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能无歧义地定位到目标即可
2、直接引用
可以直接指向目标的指针、相对偏移量或者是一个能间接定位到目标的句柄。而直接引用必须引用的目标已经在内存中存在。
3、动态链接
即符号引用替换为直接引用的阶段,该阶段会把一些静态方法(符号引用,比如main()方法)替换为指向数据所存内存的指针或句柄等(直接引用)。
初始化
初始化阶段是执行类构造器 <clinit>() 方法的过程。这一步主要的目的是:根据程序员程序编码制定的主观计划去初始化类变量和其他资源。
1、执行类构造器<clinit>()方法的过程
- 对类的静态变量初始化为指定的值,执行静态代码块
- 当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化
- 虚拟机会保证一个类的<clinit>()方法在多线程环境中被正确加锁和同步
- 当范围一个Java类的静态域时,只有真正声名这个域的类才会被初始化
2、初始化的时机
需要在主动引用时,才会执行初始化
- new、getstatic、putstatic、invokestatic
- 对内进行反射调用时
- 初始化一个类的子类会去加载其父类
- 启动程序所使用的main方法所在类
- 当使用jdk1.7动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解析结果
除了主动引用外,还有以下三种情况被称为被动引用,不会触发初始化
- 通过子类引用父类的静态字段,只会触发父类的初始化,而不会触发子类的初始化。
- 定义对象数组和集合,不会触发该类的初始化
- 类A引用类B的static final常量不会导致类B初始化(注意静态常量必须是字面值常量,否则还是会触发B的初始化)
三、触发类加载过程的时机
触发类加载过程的时机主要分为隐式加载和显示加载两种情况
隐式加载
- 创建类对象
- 使用类的静态域
- 创建子类对象
- 使用子类的静态域
- 在JVM启动时,BootStrapLoader会加载一些JVM自身运行所需的class
- 在JVM启动时,ExtClassLoader会加载指定目录下一些特殊的class
- 在JVM启动时,AppClassLoader会加载classpath路径下的class,以及main函数所在的类的class文件
显示加载
- ClassLoader.loadClass(className):只加载和连接、不会进行初始化
- Class.forName(String name, boolean initialize,ClassLoader loader):使用ClassLoader进行加载和连接,根据参数initialize决定是否初始化。
四、类加载完成后在内存中储存
类加载完成后主要包括类信息以及类Class对象,其中类信息保存在方法区中,类Class对象保存在堆区。
类信息主要包含运行时常量池、类型信息、字段信息、方法信息、类加载器的引用、对应class实例的引用等信息。
类加载器的引用:这个类到类加载器实例的引用
对应class实例的引用:类加载器在加载类信息放到方法区中后,会创建一个对应的Class 类型的对象实例放到堆(Heap)中, 作为开发人员访问方法区中类定义的入口和切入点。
JVM系列(一):JVM类加载过程详解相关推荐
- Java类加载过程详解
类的生命周期 类的加载 类加载过程 加载 链接 验证 准备 解析 初始化 总结 首先我们先简单了解一下整个JVM的体系结构是怎样的,如下图所示(图1): 再详细具体一点(图2): 上面的图片有些地方看 ...
- 最通俗易懂的JAVA虚拟机类加载过程详解,看完还不懂你考虑转行吧!
前言 当程序使用某个类时,如果该类还未被加载到内存中,则JVM会通过加载.链接.初始化三个步骤对该类进行类加载. Java Class文件 class文件是一组以8位字节为基础的二进制流,各个数据项目 ...
- SAP License:SAP ECC6安装系列四:安装过程详解
续接上篇,我们终于按下了 "Next"按钮,正式开始安装 SAP 了,下面一步步的简单进行说明,因为实在是很傻瓜的软件安装过程,唯一与众不同的,就是所需要的时间真的很长,一般来说8 ...
- JVM之类加载阶段详解
JVM之类加载阶段详解 类加载阶段总览 加载 获取二进制流 将字节流转换为运行时数据结构 堆中生成Class对象 特殊 连接 验证 准备 解析 名词解释 何时进行 解析哪些类型 初始化 类 接口 使用 ...
- 类加载顺序及加载过程详解
转自: 类加载顺序及加载过程详解 下文笔者讲述类的加载顺序及加载过程的详解说明,如下所示 java创建对象的方式分为以下四种 new 反射克隆反序列化 class对象获取的方式分享 //没有完成初始化 ...
- JVM垃圾回收算法与原理详解
垃圾回收 参考文档 GC参考手册-Java版 理解Java的强引用.软引用.弱引用和虚引用 JVM系列(五) - JVM垃圾回收算法 如何判断对象可以回收 引用计数法 参考文章 Java JVM的引用 ...
- jvm与Tomcat调优【详解】——有这一篇就够了
jvm与Tomcat调优 一.JVM性能调优 1.1 什么是JVM? 1.2 JVM调优工具 1.3 JVM调优经验 1.4常用JVM参数参考: 1.5 Java文件编译的过程 1.6 为什么说jav ...
- 内存分配策略(一):JVM栈桢及方法调用详解
JVM 线程堆栈分析过程详解 在这篇文章里我将教会你如何分析JVM的线程堆栈以及如何从堆栈信息中找出问题的根因.在我看来线程堆栈分析技术是Java EE产品支持工程师所必须掌握的一门技术.在线程堆栈中 ...
- 深入理解Java虚拟机之Java类加载机制,Java类实例化过程详解。
目录 Java类加载机制 类加载过程 加载(Loading) 连接(Linking) 初始化(Initialzation) 使用(Useing) 卸载(Unloading) 引言 什么情况下开始类加载 ...
最新文章
- 【Python】函数默认参数怎么改变?
- php 变量源码,PHP源码中变量存储方式
- 实战Makefile
- PHP关于函数的参数问题
- jdk1.8下载安装教程
- SpringBoot整合jersey
- Windows 下安装 TensorFlow 2.2 GPU 版 教程:坑多,整理出来方便大家
- 可编译易用的模块化nf-HiPAC移植成功
- 【计算机组成原理】微命令 微指令 微操作 微程序
- 发一个mir2的内挂代码
- 【外文翻译】外国友人写得很不错的Java Lambda表达式入门教程,我终于翻译好给大家啦!!!...
- 无驱、代码自动植入:新一代软件保护锁——圣天诺LDK-HL
- Pytorch分布式训练/多卡训练(二) —— Data Parallel并行(DDP)(2.2)(代码示例)(BN同步主卡保存梯度累加多卡测试inference随机种子seed)
- 内是不是半包围结构_半包围结构是什么意思 半包围结构字的书写规则
- 20年的星际争霸,再回首
- Non-parametric Classifiers
- P1497 木牛流马 题解
- Android 开发之 ContentProvider 内容提供者
- leaflet离线地图(开发总结)
- 01-Docker基本管理