JVM核心机制—类加载器

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_43319635/article/details/102710422

1.类加载机制

JVM把class文件加载到内存,并对数据校验,解析和初始化,最终形成JVM可以直接使用的java类型的过程

1.1加载

将class文件字节码加载到内存,并将这些静态数据转化成方法区中运行时的二进制的数据结构,在堆中生成一个代表类的java.Lang.Class,作为方法区类数据的访问入口
在这里插入图片描述

1.2链接

将java的二进制代码合并到jvm的运行状态之中的过程

  • 验证:确保加载的类信息符合JVM规范,没有安全方面的问题。
  • 准备:正式为变量(static变呈)分配内存并设置类变量初始值的阶段,这些内存都将在方法区中进行分配
  • 解析:虚拟机常量池内的符号弓用替换为直接引用的过程

1.3初始化

  • 初始化阶段是执行类构造器clinit()方法的过程。类构适器clinit()是由编译器自动收集
    类中的所有类变量的赋值动作和静态语句块(static块)中的语法合并产生的·
  • 当初始化一个类的时候,如果发现其父类还没有进行过初始化、则需要先对其父类初始化
  • 虚拟机会保证一个类的cilnit()方法在多线程环境中被正确加锁和同步

发生类的初始化:类的主动引用

  • new一个类的对象
  • 调用类的静态成员(除了final常量)和静态方法
  • 使用java.lang.reflect包的方法对类进行反射调用
  • 运行main方法所在的类
  • 当初始化一个类的时候,如果发现其父类还没有进行过初始化、则需要先对其父类初始化

不会发生类的初始化:类的被动引用

  • 当访问一个静态域时,只有真正声明这个域的类才会被初始化。通过子类引用父的静态变量不导致子初始化
  • 沮叟类引用,不会岌此类的初始化
  • 引用此类常量不会触发此类的初始化(常量在编译阶段就存入调用类的常量池中了)
    在这里插入图片描述

2.深入类加载器

2.1.类加载器的层次结构

  • 引导类加载器:
    加载java核心库
    不继承java.lang.classLoader
    加载扩展类加载器和应用程序类加载器
    原生代码实现

  • 扩展类加载器:
    加载java扩展库
    加载应用程序类加载器
    继承java.lang.classLoader

  • 应用程序类加载器:
    根据java应用的类路径加载java应用的类
    继承java.lang.classLoader

  • 自定义类加载器:

2.2.类加载器的代理模式

  • 代理模式, 交给其他类加载器加载

  • .双亲委托机制,某个类加载器接到加载类的请求时,优先交给父类加载器加载。保证java核心类库的安全,并不是所有加载 器都是双亲委托机制

      同一个类被不同的加载器加载,JVM也认为是不同的类
    

猜你喜欢

转载自blog.csdn.net/weixin_43319635/article/details/102710422
今日推荐