Java类加载过程

类加载三个阶段任务:
    加载和连接阶段是JVM虚拟机完成的,无法进行控制。
    初始化阶段是程序员可以控制的,例如在代码块中对静态成员初始化等。
1、加载阶段:
    JVM在该阶段主要目的是 将字节码从不同的数据源(class文件,jar包,网络等) 转化为二进制字节流
加载到内存中(将某个类的字节码二进制数据加载到方法区域) 生成一个代表该类的java.long.Class对象
2、连接阶段:
连接—验证:
    ①目的是为了 确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。 
    ②验证内容包括:文件格式验证(是否以魔数oxcafebabe开头)、元数据验证、字节码验证和符号引用验证。
    ③可以考虑使用 -Xverify:none 参数关闭大部分的类的验证措施,缩短虚拟机类加载时间。
连接—准备:
    ①JVM会在该阶段 静态变量 分配内存并 默认初始化(即int初始化为0,非基本数据类型为Null等)。
    ②这些变量所使用的 内存都将在 方法区 中进行分配。
        普通变量准备阶段不分配内存。
        静态变量准备阶段分配内存,赋值默认初始化值。
        常量一旦赋值就不变,因此直接赋值到最终值。
    
连接—解析:
    ①虚拟机将常量池内的 符号引用替换成 直接引用的过程。
    例:类A和类B具有引用关系。
           但是在连接阶段类还没有真正加载,二者引用使用符号代替的
           到了解析阶段,可以获得类由JVM分配的地址,此时将原来的符号替换成真正的引用。
3.初始化阶段
①到初始化阶段,才真正执行类中定义的Java程序代码,此阶段是执行<clinit>()方法的过程。
②<clinit>()方法是由编译器按语句在源文件中出现的 顺序,依次自动收集
    类中所有的 静态变量的赋值动作静态代码块中的语句,并进行 合并
    例:使用类的静态属性(不进行new)也会导致类的加载。
    
    类A定义和执行结果:
        
③虚拟机会保证一个类<clinit>()方法在多线程环境中被正确的加锁、同步。
   如果多个线程同时区初始化一个类,那么只有一个线程区执行这个类的<clinit>()方法,
   其他线程都需要阻塞等待,知道活动线程执行<clinit>()方法完毕。
   这个机制,保证某个类在内存中只有一份Class对象。
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值