JVM-类加载机制

5 篇文章 0 订阅

定义

Java 虚拟机负责把描述类的数据从 Class 文件加载到系统内存中,并对类的数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的 Java 类型,这个过程被称之为 Java 的类加载机制

类加载方式-两种

Java 类的加载是动态的,它不会一次性将所有类加载后再运行。为了节省内存开销,它先把保证程序运行的基础类加载到 JVM 中,其他类在需要的时候才加载。

  1. 隐式装载,程序在运行过程中通过 new 等方式生成对象时,隐式调用类装载器加载对应的类到 JVM 中
  2. 显式装载,通过 Class.forName() (反射)等方法,显式加载需要的类

类加载器

  • 启动类加载器(bootstrap class loader):

    • 用来加载 Java 的核心库,无法被 Java 程序直接引用。
    • 是用原生代码来实现的,并不继承自 java.lang.ClassLoader。
    • 它负责将 jre/lib 下面的核心类库或 -Xbootclasspath 选项指定的 jar 包加载到内存中。
  • 扩展类加载器(extensions class loader):

    • 用来加载 Java 的扩展库。
    • 由 Sun 的 ExtClassLoader (sun.misc.Launcher$ExtClassLoader)实现的。
    • 它负责将 jre/lib/ext 或者由系统变量 -Djava.ext.dirs 指定位置中的类库加载到内存中。
  • 系统类加载器(system class loader):

    • 一般 Java 应用的类都是由它来完成加载的,可以通过 ClassLoader.getSystemClassLoader()来获取。
    • 由 Sun 的 AppClassLoader(sun.misc.Launcher$AppClassLoader)实现的。
    • 它负责将系统类路径 java -classpath 或 -Djava.class.path 变量所指的目录下的类库加载到内存中。
  • 用户自定义类加载器

    • 通过继承 java.lang.ClassLoader 类的方式实现。

类加载过程(类的生命周期)

类的加载指的是将类的.class 文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个 java.lang.Class 对象,用来封装类在方法区内的数据结构。

类加载机制一共有五个步骤,分别是加载、链接、初始化、使用、卸载五个阶段。
链接阶段会细分成三个阶段,分别是验证、准备、解析
加载、链接、初始化是类的加载的过程。

  1. 加载,通过类的完全限定名,查找字节码文件,在 Java 堆中也创建一个 java.lang.Class 类的对象;
  2. 链接,链接包含三块内容:验证、准备、初始化;
    1. 验证,检查加载的 class 文件的正确性(文件格式、元数据、字节码、符号引用验证);
    2. 准备,给类变量分配内存空间,并将其初始化为默认值;
    3. 解析,虚拟机将常量池中的符号引用转换成直接引用的过程(符号引用就理解为一个标示,而在直接引用直接指向内存中的地址);
  3. 初始化,主要完成静态块执行以及静态变量的赋值。先初始化父类,再初始化当前类。只有对类主动使用时才会初始化。(创建类的实例时、访问类的静态方法或静态变量时、使用 Class.forName 反射类时、 某个子类初始化时);
  4. 使用,new 出对象程序中使用;
  5. 卸载,执行垃圾回收(Java 自带的加载器加载的类,在虚拟机的生命周期中是不会被卸载的,只有用户自定义的加载器加载的类才可以被卸载);

双亲委派模型

从 JDK 1.2 开始,类加载过程采取了双亲委派机制(PDM)。

概念:一个类加载器收到了类加载的请求,它首先不会自己去加载这个类,而是把这个请求委派给父类加载器去完成,每一层的类加载器都是如此,这样所有的加载请求都会被传送到顶层的启动类加载器中,如果此时父类不能加载,反馈给子类,由子类去尝试加载类。

PDM 更好的保证了 Java 平台的安全性,在该机制中,JVM 自带的 bootstrap 是根加载器,其他的加载器都有且仅有一个父类加载器。

如何判断一个类不再使用

  • 这个类所有的实例已经被回收,也就是 Java 堆中不存在该类及其任何这个类子类的实例
  • 加载这个类的类加载器已经被回收,但是类加载器一般很难会被回收,除非这个类加载器是为了这个目的设计的,比如 OSGI、JSP 的重加载等,否则通常很难达成。
  • 这个类对应的 Class 对象没有任何地方被引用,无法在任何时刻通过反射访问这个类的属性和方法。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值