什么是类加载机制

JVM把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被JVM直接使用的Java类型,这就是JVM的类加载机制。
如果你对Class文件的结构还不熟悉,可以参考之前的文章Class文件结构全面解析(上)Class文件结构全面解析(下)

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

类的生命周期

类从被加载到内存中,到被卸载出内存,一共分为以下几步:

  1. 加载(Loading)
  2. 验证(Verification)
  3. 准备(Preparation)
  4. 解析(Resolution)
  5. 初始化(Initialization)
  6. 使用(Using)
  7. 卸载(Unloading)

类加载的全过程,包括其中的加载验证准备解析初始化几个阶段。

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

加载

加载是类加载的第一阶段,在这一步中JVM规范要求完成了以下三件事:

  1. 通过一个类的全限定名来获取定义这个类的二进制字节流。
  2. 将这个字节流多代表的静态存储结构转化为方法区的运行时数据结构。
  3. 在内存中生成一个代表这个类的java.lang.Class对象。

以上要求其实并不具体,JVM的具体实现和应用都是比较灵活的。比如:获取这个类的二进制字节流,并没有说从哪获取,怎么获取,于是就有了从压缩包中读取(jar、war、ear)、从网络中获取(Applet)、运行时计算生成(动态代理)。对于不是数组的类的加载,我们可以定义自己的类加载器去控制字节流的获取方式。但是,对于数组类就不一样了,因为数组类本身不是通过类加载器创建的,而是JVM直接创建的。

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

验证

这一阶段是为了保证Class文件的字节流中包含的信息符合当前JVM的要求,并且不危害JVM自身的安全。大致分为以下四个阶段:

文件格式验证

验证字节流是否符合Class文件格式的规范,能不能被当前JVM处理。验证点比较多,比如:是否以魔数0xCAFEBABE开头、主次版本号是否在当前JVM的处理范围内、常量池的常量是否有不被支持的常量类型、CONSTANT_Utf8_info类型的常量中是否有不符合UTF8编码的数据等等。这个阶段是基于二进制字节流进行验证的,只有这个阶段验证通过了,字节流才能进入内存的方法区储存。

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

元数据验证

这个阶段主要是对类的元数据信息进行语义分析和校验,保证不存在不符合Java语言规范的元数据信息。比如:除了java.lang.Object以外的类是否有父类、是否继承了一个不允许被继承的类、非抽象类是否实现了其父类或接口中要求实现的所有方法、是否覆盖了父类的final字段等等。

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

字节码校验

这个阶段通过数据流和控制流分析,确保程序语义是合法的、符合逻辑的。比如:放置和使用操作栈时数据类型保证一致、保证跳转指令不会跳转到方法体以外的字节码指令上、保证方法体中的类型转换是有效的等等。

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

符号引用校验

这个阶段是对类自身以外(常量池中的各种符号引用)的信息进行匹配性校验,它发生在解析步骤中,确保解析能正常执行,比如:符号引用中通过字符串描述的全限定名是否能找到对应的类、符号引用中的类字段方法的访问性是否可以访问当前类等等。

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

准备

在这个阶段里,为静态变量分配内存并设置静态变量初始值。这里说的初始值通常情况下,不是代码中写的初始值,而是数据类型的零值。代码中写的初始值,是在初始化阶段赋值的。如果是静态常量(被final修饰),这个阶段就会被直接赋值为代码中写的初始值。

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

解析

在这个阶段里,JVM把常量池内的符号引用替换为直接引用。符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能无歧义地定位到目标即可,它和JVM实现的内存布局无关。直接引用可以是直接指向目标的指针、相对偏移量或是一个能间接定位到目标的句柄,它是和JVM实现的内存布局相关的。如果有了直接引用,那么引用的目标肯定在内存中存在。

解析主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符的符号引用进行,分别对应常量池的CONSTANT_Class_info、CONSTANT_Fieldref_info、CONSTANT_Methodref_info、CONSTANT_InterfaceMethodref_info、CONSTANT_MethodType_info、CONSTANT_MethodHandle_info和CONSTANT_InvokeDynamic_info。

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

初始化

初始化阶段才真正开始执行类中定义的字节码,也是执行类构造器()方法的过程。()方法是由编译器自动收集类中的所有静态变量的赋值动作和静态语句块中的语句合并产生的,编译器收集的顺序是用语句在源文件中出现的顺序所决定的,静态语句块只能访问到定义在静态语句块之前的变量,定义在它之后的变量,静态语句块可以赋值,但是不能访问。

JVM会保证在子类的()方法执行之前,父类的()方法已经执行完毕,也就是说父类中定义的静态语句块要优先于子类的变量赋值操作。如果类没有静态语句块,也没有对静态变量赋值,编译器就不会为这个类生成()方法。接口的()方法不需要先执行父接口的()方法,只有当父接口中定义的变量使用时,父接口才会被初始化。

JVM会保证一个类的()方法在多线程环境中被正确地加锁、同步。如果一个线程在执行这个类的()方法,其他线程都需要阻塞等待,当()方法执行完后,其他线程也不会再次进入()方法。同一个类加载器下,一个类只会被初始化一次。

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

结语

这次我们了解了类加载过程的几个阶段,分别是加载验证准备解析初始化加载是把二进制字节码载入内存,验证是校验字节流中包含的信息是否符合当要求,准备是为静态变量分配内存并设置静态变量初始值,解析是把常量池内的符号引用替换为直接引用,初始化是执行所有静态变量的赋值动作和静态语句块中的语句。

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

JVM的类加载机制全面解析的更多相关文章

  1. 面试必问:JVM类加载机制详细解析

    前言 在Java面试中,简历上有写JVM(Java虚拟机)相关的东西,JVM的类加载机制基本是面试必问的知识点. 类的加载和卸载 JVM是虚拟机的一种,它的指令集语言是字节码,字节码构成的文件是cla ...

  2. JVM内存结构 JVM的类加载机制

    JVM内存结构: 1.java虚拟机栈:存放的是对象的引用(指针)和局部变量 2.程序计数器:每个线程都有一个程序计数器,跟踪代码运行到哪个位置了 3.堆:对象.数组 4.方法区:字节流(字节码文件) ...

  3. JVM之类加载机制

    JVM之类加载机制 JVM类加载机制分为五个部分:加载,验证,准备,解析,初始化,下面我们就分别来看一下这五个过程. 类加载五部分 加载 加载是类加载过程中的一个阶段,这个阶段会在内存中生成一个代表这 ...

  4. 【转】JVM类装载机制的解析,热更新的探讨

    引言 如有错误,请批评指正. Java是一种动态连接的语言.所谓动态连接,大概可以这么解释. 首先,Java可以大概想象成是编译解释执行的.对于一个*.java的文件,通过javac将会编译成一个*. ...

  5. 大白话谈JVM的类加载机制

    前言 我们很多小伙伴平时都是做JAVA开发的,那么作为一名合格的工程师,你是否有仔细的思考过JVM的运行原理呢. 如果懂得了JVM的运行原理和内存模型,像是一些JVM调优.垃圾回收机制等等的问题我们才 ...

  6. 一文教你读懂JVM的类加载机制

    Java运行程序又被称为WORA(Write Once Run Anywhere,在任何地方运行只需写入一次),意味着我们程序员小哥哥可以在任何一个系统上开发Java程序,但是却可以在所有系统上畅通运 ...

  7. JVM的类加载机制

    虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 类加载的过程: 包括加载.链接(含验证.准备 ...

  8. 【JVM】类加载机制

    原文:[深入Java虚拟机]之四:类加载机制 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载.验证.准备.解析.初始化.使用和卸载七个阶段.它们开始的顺序如下图所示: 类加 ...

  9. 深入理解JVM(3)——类加载机制

    1.类加载时机 类的整个生命周期包括了:加载( Loading ).验证( Verification ).准备( Preparation ).解析( Resolution ).初始化( Initial ...

随机推荐

  1. ThreadPoolExecutor源码中的适配器模式

    什么是适配器模式 网上已有很多的教程,不细讲了.可以参考:五分钟了解设计模式(3)---适配器模式 在适配器模式中,一定要识别清楚,Target Adaptee Adapter分别是哪些类或接口,这样 ...

  2. Google Tensorflow 迁移学习 Inception-v3

    附上代码加数据地址 https://github.com/Liuyubao/transfer-learning ,欢迎参考. 一.Inception-V3模型 1.1 详细了解模型可参考以下论文: [ ...

  3. reduce,map,filter 的用法

    # filter用法 (对每一个数据进行筛选,满足条件的就保留)# 1,filter(功能函数,容器类型数据)# 2,过滤出来是一个地址,用list,或tuple进行包装# 3,过滤出来的是原容器类型 ...

  4. android studio ndk 环境配置成eclipse模式

    gradle.properties: android.useDeprecatedNdk=true build.gradle: android { ... sourceSets.main { jni.s ...

  5. [考试反思]1029csp-s模拟测试93:殇逝

    并不是把它消成上三角矩阵 停止! 思考, 回顾. 疑惑? 遗忘… 一直只是在匆忙的赶进度,实际上的确是一点也不扎实. T1,裸的偏序,想了一个多小时什么也没想到,只打了$O(n^2)$ 难道之前学的就 ...

  6. NOIP模拟 22

    剧情回放:xuefeng:考场上你们只打暴力不打正解,我不满意! skyh:考场怒切T2以表明自己拥护xuefeng的决心 BoboTeacher:这场考试就没想让你们上100 神犇skyh:(笑而不 ...

  7. 带你上手一款下载超 10 万次的 IDEA 插件

    作者 | 倪超(银时) 阿里云开发者工具产品专家 本文整理自 11 月 7 日社群分享,每月 2 场高质量分享,点击加入社群. 导读:Cloud Toolkit 是本地 IDE 插件,帮助开发者更高效 ...

  8. 『题解』Codeforces2A Winner

    Portal Portal1: Codeforces Portal2: Luogu Description The winner of the card game popular in Berland ...

  9. linux 相关指令

    modinfo   *.ko     显示驱动文件的信息.

  10. PHP关于access_token失效问题

    PHP关于access_token失效问题 有时候PHP设置了缓存 明明就是没有过期 但却提示失效这情况一般就是1 多个appid和secrete 生成的access_token互相覆盖了 所以 这种 ...