虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。下面来总结梳理类加载的五个阶段。

类加载发生在程序运行期间,会有一些性能开销,但是会提供灵活性,Java动态扩展的特性就是依赖运行时期动态加载和动态连接特点

类加载分为五个阶段:

  1. 加载
  2. 验证
  3. 准备
  4. 解析
  5. 初始化

后四个阶段统称为“连接”阶段

加载

加载阶段,虚拟机完成以下三件事:

  • 通过一个类的全限定名来获取此类的二进制字节流(即class文件);
  • 将字节流的静态存储结构转化为方法区的运行时数据结构;
  • 内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问接口;

注意

  1. 虚拟机规范中未规定方法区中的运行时数据结构,由虚拟机自行定义;
  2. 实例化的java.lang.Class对象未明确规定存储在堆中,HotSpot中的class对象存在方法区中

加载阶段尚未完成时,后续连接解读那可能已经开始

验证

验证阶段主要是为了确保class文件字节流中的信息符合虚拟机要求,不会危害虚拟机自身安全。主要有以下几种格式验证:

  • 文件格式验证:验证是否符合Class文件规范
  • 元数据验证:字节码语义分析,是否符合Java语言要求
  • 字节码验证:验证类的方法体,保证运行不会产生危害
  • 符号引用验证:验证符号引用是否能找到对应的类,是否具有访问权限等

对于反复使用和验证过的代码,可以使用-Xverify:none 可以关闭类验证措施,以缩短类加载时间。因为平时开发中idea和eclipse等工具的验证功能很完善,能保证代码准确。

准备

为static变量分配空间,不包括实例变量,实例变量会在对象实例化时和对象一起分配在堆中,

  • static分配空间在“准备”阶段(在方法区中分配),赋值在“初始化”阶段。例如 public static int value = 123 会在准备阶段设置初始值0,在初始化阶段赋值“123”;
  • static+final修饰基本数据类型和字符串常量时,分配空间和赋值都是在准备阶段,可以借此优化代码
  • static+final修饰引用类型,即用new初始化时,是在构造方法中分配空间和赋值,即在初始化阶段完成

解析

将常量池中的符号引用解析为直接引用。那么问题来了,什么是符号引用和直接引用:

  • 符号引用:描述目标的符号,与虚拟机内存布局无关,以字面量的形式明确定义在class文件中。Java虚拟机内存布局各不相同,但是符号引用必须一致。Java类编译时,不知道引用的类的实际地址,因此使用符号引用。
  • 直接引用:直接指向目标的指针、相对偏移量或是一个能间接定位到目标的句柄。同一个符号引用在不同虚拟机实例上翻译出来的直接引用一般不会相同。

解析动作针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符7类符号引用进行。

初始化:

常说的“类加载时机”与“初始化时机”一一对应。因为要进入初始化阶段,就必须要完成加载、验证、准备、解析等阶段。

初始化发生时机如下:

  • main方法所在类总是会被首先初始化
  • 首次访问这个类的静态变量或静态方法时会导致初始化
  • 子类初始化会联动父类初始化
  • 通过子类访问父类静态变量,只会触发父类初始化
  • Class.forName
  • new会导致初始化

以下情况不会导致类初始化的情况:

  • static final不会触发初始化
  • 访问类对象.class
  • 创建该类的数组
  • 类加载器的loadClass方法
  • Class.forName的参数2为false

初始化阶段实际上是执行类构造器<clinit>()方法的过程。<clinit>()会根据源文件中顺序收集类中所有类变量赋值动作和static块语句

注意:static块能访问代码块之前的变量,之后的变量可以赋值,但不能访问

<clinit>()方法的执行有如下特点:

  • 第一个执行clinit方法的一定是Object类
  • 父类中静态语句块一定优先于子类
  • 如果类中没有static方法和变量,不会产生clinit方法
  • 接口中如果有static变量,也会生成clinit,但是子接口不会执行父接口中的clinit,接口的实现类也不会调用接口中的clinit
  • 多线程时,只会有一个线程会去执行clinit,会加锁,保证线程安全

【JVM】类加载时机与过程的更多相关文章

  1. 从一道面试题来认识java类加载时机与过程

    说明:本文的内容是看了<深入理解Java虚拟机:JVM高级特性与最佳实践>后为加印象和理解,便记录了重要的内容. 1  开门见山 以前曾经看到过一个java的面试题,当时觉得此题很简单,可 ...

  2. java类加载时机与过程

    转自:http://www.tuicool.com/articles/QZnENv 说明:本文的内容是看了<深入理解Java虚拟机:JVM高级特性与最佳实践>后为加印象和理解,便记录了重要 ...

  3. 从一道面试题来认识java类加载时机与过程【转】

    说明:本文的内容是看了<深入理解Java虚拟机:JVM高级特性与最佳实践>后为加印象和理解,便记录了重要的内容. 1  开门见山 以前曾经看到过一个java的面试题,当时觉得此题很简单,可 ...

  4. 【转载】java类加载时机与过程

    1  开门见山 以前曾经看到过一个java的面试题,当时觉得此题很简单,可是自己把代码运行起来,可是结果并不是自己想象的那样.题目如下: class SingleTon { private stati ...

  5. 【深入Java虚拟机】一 JVM类加载过程

    首先Throws(抛出)几个自己学习过程中一直疑惑的问题: 1.什么是类加载?什么时候进行类加载? 2.什么是类初始化?什么时候进行类初始化? 3.什么时候会为变量分配内存? 4.什么时候会为变量赋默 ...

  6. JVM类加载过程学习总结

    JVM类加载过程学习总结 先不说JVM类加载的原理,先看实例: NormalTest类,包含了一个静态代码块,执行的任务就是打印一句话. /** * 在正常类加载条件下,看静态代码块是否会执行 * @ ...

  7. (二十七)JVM类加载器机制与类加载过程

    一.Java虚拟机启动.加载类过程分析 下面我将定义一个非常简单的java程序并运行它,来逐步分析java虚拟机启动的过程. package org.luanlouis.jvm.load; impor ...

  8. JVM类加载过程详细分析

    双亲委派加载模型 为什么需要双亲委派加载模型 主要是为了安全,避免用户恶意加载破坏JVM正常运行的字节码文件,比如说加载一个自己写的java.util.HashMap.class.这样就有可能造成包冲 ...

  9. JVM -- 类加载的过程

    类的加载过程? 一个Java文件从编码完成到最终执行,一般主要包括"编译"和"运行"两个过程.编译,即把我们写好的java文件,通过javac命令编译成字节码, ...

随机推荐

  1. 用思维导图软件MindManager整理假期

    今天带大家使用MindManager2020软件构建出2020年的节假日思维导图. 既然是做2020年的节假日思维导图,那么有个MindManager技巧就是,关于这一类思维导图我们都可以选择时间线导 ...

  2. 几分钟看懂EasyRecovery数据恢复原理,比我想象的简单易懂得多

    可能很多人知道使用数据恢复软件EasyRecovery可以恢复丢失的数据,但是却不知道它是什么原理.现在我们就以硬盘数据恢复为例,一起来了解下EasyRecovery数据恢复原理. 当硬盘数据丢失后, ...

  3. iMindMap组织结构视图在工作上的应用体现在哪些方面

    iMindMap的组织结构图视图,可以将信息.想法和流程整合起来.本文,我们将讲述iMindMap组织结构图视图的3个实例应用. iMindMap组织结构视图 简化您的工作流程 通过在工作中构建组织结 ...

  4. H5系列之svg

    svg呢,跟canvas其实都是用来画图的,只不过svg画的图,是矢量图,矢量图有个特点是,放大缩小,不会失真,canvas呢,是逐像素进行渲染的. 也就是,他依赖分辨率,会根据分辨率来决定图形是否清 ...

  5. 人人都能学会系列之ThreadLocal

    1.概览 本文我们来看下java.lang包中的ThreadLocal,它赋予我们给每个线程存储自己数据的能力. 2.ThreadLocal API ThreadLocal允许我们存储的数据只能被特定 ...

  6. 安装卸载nginx

    http://www.nginx.cn/install ubuntu和debain下的apt方式安装软件很方便,特别是对于新手安装和卸载nginx. 由于nginx不能动态添加模块,所以会经常安装和卸 ...

  7. zabbix 监控ssh 登入与报警!!!!

    配置自定义键值 vim /etc/zabbix/zabbix_agentd.d/sanguo_check_ssh.conf 添加自定义键值 UserParameter=sanguo.check.ssh ...

  8. js 表格上checkbox 全选

    <table class="layui-table"> <thead> <tr> <th width="75"> ...

  9. Android动画系列之属性动画

    原文首发于微信公众号:jzman-blog,欢迎关注交流! 属性动画相较帧动画和补间动画更强大,帧动画和补间动画只能应用于 View 及其子类,而属性动画可以修改任何对象的属性值,属性值可在指定的一段 ...

  10. 口述完SpringMVC执行流程,面试官就让同事回家等消息了

    Srping MVC 执行流程真的是老生常谈的话题了,最近同事小刚出去面试,前面面试官相继问了几个 Spring 相关的问题,但当面试官问他,你知道 Srping MVC 的执行流程吗?小刚娴熟的巴拉 ...