JVM类加载机制

本文详细介绍了Java的类加载过程,包括加载、验证、准备、解析和初始化五个阶段。类加载器在运行期间动态加载类,确保类型的安全性和正确性。初始化阶段,虚拟机规范了特定场景下必须立即初始化类的情况。类加载涉及到静态字段的赋值、符号引用到直接引用的转换等关键步骤,确保程序的正常运行。此外,还讨论了类加载器的角色和类的生命周期。
摘要由CSDN通过智能技术生成

前言

  java秉承“一次编写,到处运行”的理念,其平台无关系得益于JVM(Java虚拟机)的存在,其并不仅仅与java语言绑定,而是与“Class”文件(字节码文件)所关联,任何可以编译成Class文件的语言都可以被JVM识别。
  Class文件中的信息,最终都要加载到JVM中才能运行和使用,Java语言中,类型的加载、连接、初始化均在程序运行期间完成,为其反射即动态扩展提供了支持。
  因此,一个.java文件到最终被执行,一共经历了两个阶段:

    1. 编译:从.java文件通过java编译器(javac命令)编译为class文件
    2. 运行:把编译好的class文件交给jvm运行

  来自《深入理解Java虚拟机》中看到的一句很喜欢的话:
    “代码编译的结果从本地机器码转变为字节码,在存储格式发展的一小步,却是编程语言发展的一大步。”

类加载过程

  就是把编译好的class文件交给jvm运行的过程,从类被加载到JVM内存,到卸载出内存,整个生命周期如下,其中验证、准备、解析部分统称为连接。
类的生命周期
  生命周期的第一步加载时机交给JVM自己把控。但初始化阶段,虚拟机规范了5中必须立即初始化的场景(加载、验证、准备需要在初始化之前开始):

   1. 使用new初始化对象、读取或设置一个静态字段、调用一个静态方法
   2. 对类反射调用
   3. 初始化类时发现父类还未初始化,则优先触发父类初始化
   4. 虚拟机启动时的主类(包含main方法的那个类)
   5. JDK1.7动态语言支持场景

加载

  “加载”是类加载过程的一个阶段。其通过类名将class文件使用类加载器加载入内存生成Class对象。

验证

  校验Class文件中信息正确性及安全性

准备

  为类变量方法区中分配内存,并设置初始值。

  • 此时分配的只有类变量(static修饰的变量),不包含实例变量,实例变量将在对象实例化时随对象分配在堆中。
  • 且此时设置的初始值不是程序员所赋予的值,而是默认值,例如:public static int temp = 3; 此时初始化赋值是0不是3。

解析

  JVM将常量池内符号引用替换为直接引用
  例如:int SUM_NUM = xxx; 其中SUM_NUM就是符号引用,其指向的地址ffff就是直接引用

  符号引用

     由于Java是运行时动态连接,因此在初始Class文件中无法预知最终内存布局,符号引用就是那些还没经过运行期转换成真正内存入口的字段、方法的符号;当JVM运行时,需要从常量池获得对应的符号引用,在解析时翻译到具体的内存地址中。

  直接引用

     可以直接指向目标内存的指针、句柄等。直接引用是和虚拟机实现内存布局相关的,不同的虚拟机内存布局不同。

初始化

  此时真正开始执行Java代码。
  在准备阶段,为类变量设置了初始值;而在初始化阶段,开始真正赋予程序员设定的值。例如:public static int temp = 3; 此时的赋值是3而不是0。此时类变量仍然不包括实例变量。

  •   类变量赋值,即执行静态语句块或类变量的赋值动作
  •   子类要执行,那么如果调用了父类的,父类也必须执行完毕。因此第一个被执行的肯定是Object类
  •   JVM保证静态赋值线程安全。多个线程同时去初始化一个类,只有一个线程去执行初始化,其余线程阻塞,直到活动线程初始化完毕。

类加载器

传送门我的另一篇博客:
https://blog.csdn.net/qq_26012495/article/details/106631498?spm=1001.2014.3001.5501

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值