zoukankan      html  css  js  c++  java
  • JVM -- 类加载的过程

    类的加载过程?

    一个Java文件从编码完成到最终执行,一般主要包括”编译”和”运行”两个过程.编译,即把我们写好的java文件,通过javac命令编译成字节码,也就是我们常说的.class文件。运行,则是把编译生成的.class文件交给Java虚拟机(JVM)执行。而类加载过程即是指JVM虚拟机把.class文件中类信息加载进内存,并进行解析生成对应的class对象的过程。

    类的生命周期会经历以下 7 个阶段:

    加载阶段(Loading)
    验证阶段(Verification)
    准备阶段(Preparation)
    解析阶段(Resolution)
    初始化阶段(Initialization)
    使用阶段(Using)
    卸载阶段(Unloading)
    其中验证、准备、解析 3 个阶段统称为连接(Linking),如下图所示:

    我们平常所说的 JVM 类加载通常指的就是前五个阶段:加载、验证、准备、解析、初始化等,接下来我们分别来看看。

    1. 加载阶段
    此阶段用于查到相应的类(通过类名进行查找)并将此类的字节流转换为方法区运行时的数据结构,然后再在内存中生成一个能代表此类的 java.lang.Class 对象,作为其他数据访问的入口。

    小贴士:需要注意的是加载阶段和连接阶段的部分动作有可能是交叉执行的,比如一部分字节码文件格式的验证,在加载阶段还未完成时就已经开始验证了。

    2. 验证阶段
    此步骤主要是为了验证字节码的安全性,如果不做安全校验的话可能会载入非安全或有错误的字节码,从而导致系统崩溃,它是 JVM 自我保护的一项重要举措。

    验证的主要动作大概有以下几个:

    文件格式校验包括常量池中的常量类型、Class 文件的各个部分是否被删除或被追加了其他信息等;
    元数据校验包括父类正确性校验(检查父类是否有被 final 修饰)、抽象类校验等;
    字节码校验,此步骤最为关键和复杂,主要用于校验程序中的语义是否合法且符合逻辑;
    符号引用校验,对类自身以外比如常量池中的各种符号引用的信息进行匹配性校验。
    3. 准备阶段
    此阶段是用来初始化并为类中定义的静态变量分配内存的,这些静态变量会被分配到方法区上。

    HotSpot 虚拟机在 JDK 1.7 之前都在方法区,而 JDK 1.8 之后此变量会随着类对象一起存放到 Java 堆中。

    4. 解析阶段
    此阶段主要是用来解析类、接口、字段及方法的,解析时会把符号引用替换成直接引用。

    所谓的符号引用是指以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能无歧义地定位到目标即可;而直接引用是可以直接指向目标的指针、相对偏移量或者是一个能间接定位到目标的句柄。

    符号引用和直接引用有一个重要的区别:使用符号引用时被引用的目标不一定已经加载到内存中;而使用直接引用时,引用的目标必定已经存在虚拟机的内存中了。

    5. 初始化
    初始化阶段 JVM 就正式开始执行类中编写的 Java 业务代码了。到这一步骤之后,类的加载过程就算正式完成了。

    Java自身提供了哪些类加载器?

    1)启动类加载器(Bootstrap ClassLoader),C++实现,在java里无法获取,负责加载/lib下的类。

    2)扩展类加载器(Extension ClassLoader),Java实现,可以在java里获取,负责加载/lib/ext下的类。

    3)应用程序类加载器(Application ClassLoader),是与我们接触较多的类加载器,我们写的代码默认就是由它来加载,ClassLoader.getSystemClassLoader返回的就是它

    双亲委派模型怎么理解?

    是什么?

    双亲委派的意思是如果一个类加载器需要加载类,那么首先它会把这个类请求委派给父类加载器去完成,每一层都是如此。一直递归到顶层,当父加载器无法完成这个请求时,子类才会尝试去加载。(即每个儿子都不愿意干活,每次有活就丢给父亲去干,直到父亲说这件事我也干不了时,儿子自己想办法去完成。)

    为什么要用(作用,必要性)?

    因为在Java中任意一个类在JVM中的唯一性都是由这个类本身和加载这个类的类加载器来确定的。所以如果不是同一个类加载器加载,即时是相同的class文件,也会出现判断类不相同的情况,从而引发一些意想不到的情况,为了保证相同的class文件,在使用的时候,是相同的对象,JVM设计的时候,采用了双亲委派的方式来加载类。

    参考/好文:

    说说双亲委派 --

    https://baijiahao.baidu.com/s?id=1633056679004596814&wfr=spider&for=pc

    双亲委派是什么? --

    https://blog.csdn.net/qq_22771739/article/details/86163254

    浅谈双亲委派和破坏双亲委派  --

    https://www.cnblogs.com/joemsu/p/9310226.html

  • 相关阅读:
    apache安全—用户访问控制
    hdu 3232 Crossing Rivers 过河(数学期望)
    HDU 5418 Victor and World (可重复走的TSP问题,状压dp)
    UVA 11020 Efficient Solutions (BST,Splay树)
    UVA 11922 Permutation Transformer (Splay树)
    HYSBZ 1208 宠物收养所 (Splay树)
    HYSBZ 1503 郁闷的出纳员 (Splay树)
    HDU 5416 CRB and Tree (技巧)
    HDU 5414 CRB and String (字符串,模拟)
    HDU 5410 CRB and His Birthday (01背包,完全背包,混合)
  • 原文地址:https://www.cnblogs.com/liaowenhui/p/13871082.html
Copyright © 2011-2022 走看看