zoukankan      html  css  js  c++  java
  • Java Virtual Machine ClassLoader

    Java Virtual Machine ClassLoader

    下面讨论的都是在JDK8 platform。

    JVM内存区中药创建对象,就必须需要把.class文件加载到内存中才能使用。

    类加载大概分为5个阶段

    加载验证准备解析初始化

    加载 Loading

    加载的过程,就是JVM读取.class 文件的二进制字节流,将这个字节流代表的静态存储 结构 转化为方法区的运行时数据结构,然后在Heap中创建一个对象,作为方法区这个类的访问入口。除了从.class文件获取,也可以从jar。war中获取,还可以通过动态代理proxy生成

    验证 Verification

    验证主要是用于确保class文件符合JVM的要求

    准备 Prepatation

    准备阶段是在方法区中为类变量(static 变量)分配内存并设置初始值。此时的分配变量属于类变量,不包括实例变量。 static变量在准备阶段初始为0,如果设置其他自定义值就需要在对象初始化的时候完成。但是如果是final类型,

    public static final int value =1111;
    

    JVM在准备阶段就会给该变量赋值1111。

    解析 Resolution

    主要是对类或接口,字段,类方法,接口方法,方法类型,方法句柄,调用点等7类符号引用进行处理。分别是常量池的

    CONSTANT_Class_info,

    CONSTANT_Fieldref_info,CONSTANT_Methodref_info,CONSTANT_InterfaceMethodref_info,CONSTANT_MethodType_info,CONSTANT_MethodHandle_info,CONSTANT_Dynamic_info,CONSTANT_InvokeDynamic_info

    初始化 Initialization

    通过执行<clinit> 方法为类进行初始化。<clint>方法是有编译器自动收集类中的所有类变量的赋值动作和静态语句块static{}中的语句合并产生的。

    JVM保证子类的<clint>方法执行前,父类的<clint>方法已经执行完毕,所以意味着父类中定义的静态语句块要优先与子类的变量赋值操作

    类加载器 ClassLoader

    image-20210629215622607

    先上图 3大类加载器,启动类加载器,扩展类加载器,应用程序类加载器。

    Coder还可以extend ClassLoader来自定义加载器。

    启动类加载器 BootStrap ClassLoader

    负责加载核心的类库lib目录下的或者被-Xbootclasspath参数指定的路径而且是JVM能识别的。BootStrap ClassLoader不能被java程序直接使用,当编写自定义类加载器是,需要把加载请求委派给引导类加载器处理。

    扩展类加载器 Extension ClassLoader

    负责加载libext,或者是被java.ext.dirs 系统变量所指定的路径下所有的库。

    应用程序类加载器 Application ClassLoader

    负责加载用户路径classpath上的类库

    双亲委派模型 Parents Delegation Model

    双亲委派模型要求除了Bootstrap ClassLoader之外,其他的类加载器都应该有自己的父类加载器。这里加载器之间的父子关系不是继承来实现的,而是通过组合Composition来复用父加载器。

    如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类, 而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此, 因此所有的加载请求最终都应该传送到最顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类) 时, 子加载器才会尝试自己去完成加载 。

    这个特别的机制是为了保障类的唯一性和安全性。确保各自的类只会被对应的加载器加载

    jvm = Java Virtual Machine

    参考:

    https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html

    Tag

    jvm classloader

  • 相关阅读:
    Reactor系列(四)subscribe订阅
    Reactor系列(三)创建Flux,Mono(续)
    Reactor系列(二)Flux Mono创建
    Reactor系列(一)基本概念
    Stream系列(十五)File方法使用
    Stream系列(十四)parallet方法使用
    OpenCV二值化、归一化操作
    C# 队列
    linux shell脚本程序路径作为变量
    C++中头文件(.h)和源文件(.cpp)都应该写些什么
  • 原文地址:https://www.cnblogs.com/dreamtaker/p/14954174.html
Copyright © 2011-2022 走看看