• Java 类加载机制


          类从被加载到虚拟机内存中开始,到卸载出内存,它的整个生命周期包括:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initiallization)、使用(Using)和卸载(Unloading)这7个阶段。其中验证、准备、解析3个部分统称为连接(Linking)

     加载Loading

    1、预加载。虚拟机启动时加载,加载的是JAVA_HOME/lib/下的rt.jar下的.class文件,这个jar包里面的内容是程序运行时非常常常用到的,像java.lang.*、java.util.*、java.io.*等等,因此随着虚拟机一起加载。

    2、运行时加载。虚拟机在用到一个.class文件的时候,会先去内存中查看一下这个.class文件有没有被加载,如果没有就会按照类的全限定名来加载这个类。

    加载阶段:

    • 获取.class文件的二进制流 

    • 将类信息、静态变量、字节码、常量这些.class文件中的内容放入方法区中

    • 在内存中生成一个代表这个.class文件的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。一般这个Class是在堆里的。

    验证

    目的是为了确保.class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。

    验证阶段:

     1、文件格式验证

                                   (.class文件的第5~第8个字节表示的是该.class文件的主次版本号,验证的时候会对这4个字节做一个验证,高版本的JDK能向下兼容以前版本的.class文件,但不能运行以后的class文件,即使文件格式未发生任何变化,虚拟机也必须拒绝执行超过其版本号的.class文件)

    注:抛出java.lang.UnsupportedClassVersionError----------》JDK版本问题

    2、元数据验证

    3、字节码验证

    4、符号引用验证

    准备

    准备阶段是正式为类变量分配内存并设置其初始值的阶段,这些变量所使用的内存都将在方法区中分配。

    1、这时候进行内存分配的仅仅是类变量(被static修饰的变量),而不是实例变量,实例变量将会在对象实例化的时候随着对象一起分配在Java堆中 

    2、这个阶段赋初始值的变量指的是那些不被final修饰的static变量,比如”public static int value = 123;”,value在准备阶段过后是0而不是123,给value赋值为123的动作将在初始化阶段才进行;比如”public static final int value = 123;”就不一样了,在准备阶段,虚拟机就会给value赋值为123。

     解析

    解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程

    初始化

    初始化阶段是类加载过程的最后一步,初始化阶段是真正执行类中定义的Java程序代码(或者说是字节码)的过程。初始化过程是一个执行类构造器<clinit>()方法的过程

    虚拟机会保证类的初始化在多线程环境中被正确地加锁、同步,即如果多个线程同时去初始化一个类,那么只会有一个类去执行这个类的<clinit>()方法,其他线程都要阻塞等待,直至活动线程执行<clinit>()方法完毕。

  • 相关阅读:
    apache性能测试工具
    redis和memcacahe、mongoDB的区别
    redis 安装
    redis介绍
    svn基本命令
    变量
    redis持久化有几种.如何配置
    Sundy_Android开发深入浅出和高级开发视频教程
    VC++ MFC类库基础(55讲全)
    从C++起步到MFC实战VC++软件工程师高端培训 视频保存在 播音员的网盘中
  • 原文地址:https://www.cnblogs.com/KL2016/p/15895764.html
Copyright © 2020-2023  润新知