java虚拟机(HotSpot)之类加载器

本文详细探讨了Java虚拟机(HotSpot)的类加载过程,包括加载、验证、准备、解析和初始化阶段。文章还介绍了类加载器的分类,如Bootstrap、扩展和应用类加载器,并详细阐述了双亲委派机制。此外,重点讨论了类的主动使用和被动使用的区别。最后,通过代码示例展示了类加载顺序,并简要提及了运行时数据区的概念。
摘要由CSDN通过智能技术生成

Jvm类加载器

一、Jvm生命周期

虚拟机的启动:
   虚拟机的启动是通过引导类加载器创建一个初始类来完成的,这个类是由虚拟机的具体实现指定的

虚拟机的执行:
   一个运行中的java虚拟机有着一个清晰的任务,
   执行java程序程序开始执行时它才运行,程序结束时停止
   执行一个所谓的java程序的时候,真真正正在执行的·是一个叫做java虚拟机的进程

退出:
   正常结束 
   异常
   System.exit()

二,类加载

类加载器只负责加载class文件,至于是否可以运行,由执行引擎来讲决定的。
加载的类信息存放在于一块称为方法区的内存空间,除了类的信息外,方法区中还会
会存放运行时常量池的信息,可能还包括字符串字面量和数字常量(这部分常量信息是
class文件中常量池部分的内存映射)。

1.类的加载过程

 加载  --  (验证 --  准备 --- 解析)  ---  初始化
                   链接



加载:
   1.通过一个类的全限定名获取此类的二进制字节流
   2.将这个字节流所代表的静态存储结构转换为方法区的运行时数据结构
   3.在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口

验证:
   1.目的在于确保class文件的字节流中包含信息符合当前虚拟机要求,保证被加载类的正确性,
     不会危害虚拟机自身安全。
   2.主要包括四种验证,文件格式验证,元数据验证,字节码验证,符号引用验证

准备:
   1.为类变量分配内存并且设置该类静态变量的默认初始值,即零值。
   2.这里不包含用fina修饰的static,因为final在编译的时候就会分配了,准备阶段会显式初始化,。
      如果是非显式的赋值,则会再类初始化的时候赋值。
   3.这里不会实例化变量分配初始化,类变量会分配在方法区中,而实例变量是会随着对象一起分配到java堆中


解析 :
   1.将常量池内的符号引用转换为直接引用的过程。
   2.事实上,解析操作往往会伴随着jvm在执行完初始化之后再执行。
   3.符号引用就是一组符号来描述所引用的目标,符号引用的字面量形式明确定义在class文件格式中,
   4.直接引用就是直接指向目标的指针,相对偏移量或一个间接定位到目标的句柄。
   5.解析动作主要针对类或接口,字段,类方法,接口方法,方法类型等,   

初始化:
   初始化阶段就是执行类构造器方法<clinit>()的过程。带有static修饰的也会初始化,如静态方法,静态块,
   此方法不需要定义,是java编译器自动收集类中的所有静态类变量的赋值动作和静态代码块中的语句合并而来。
   并且给静态变量赋予初始值,如果程序对静态变量的值进行了赋值或修改,都是以代码的顺序来的,而且注意,
   只能执行带有static关键字的属性和静态块
   
   构造器方法中的指令按语句在源文件中出现的顺序执行。
   
    <clinit>()不同于类的构造器(构造器是虚拟机视角下的<init>())。
    
    若该类具有父类,jvm会保证子类的<clinit>()执行前,父类的<clinit>()已经执行完毕。
    虚拟机必须保证一个类的<clinit>()方法在多线程下被同步加锁,
    如果多个线程同时去初始化一个类,那么只会有一个线程去执行这个类的类构造器<clinit>(),
    其他线程都需要阻塞等待,直到活动线程执行<clinit>()方法完毕。
     
    特别需要注意的是,在这种情形下,其他线程虽然会被阻塞,但如果执行<clinit>()方法的那条线程退出后,
    其他线程在唤醒之后不会再次进入/执行<clinit>()方法,因为 在同一个类加载器下,
    一个类型只会被初始化一次。
    如果在一个类的<clinit>()方法中有耗时很长的操作,就可能造成多个线程阻塞,
    在实际应用中这种阻塞往往是隐藏的
   
     注意:带有static修饰的代码都是被clinit来执行的,因此,延申一个问题就是,
           单例模式使用静态内部类是线程安全的,

2.四种验证方式

   文件格式验证,元数据验证,字节码验证,符号引用验证

 文件格式验证: 
    是要验证字节流是否符合Class文件格式的规范,并且能被当前版本的虚拟机处理。
    如验证魔数是否0xCAFEBABE;主、次版本号是否正在当前虚拟机处理范围之内;
    常量池的常量中是否有不被支持的常量类型……该验证阶段的主要目的是保证输入的字节流能
    正确地解析并存储于方法区中,经过这个阶段的验证后,字节流才会进入内存的方法区中存储,
    所以后面的三个验证阶段都是基于方法区的存储结构进行的。

 元数据认证:
   是对字节码描述的信息进行语义分析,以保证其描述的信息符合Java语言规范的要求。
   可能包括的验证如:这个类是否有父类;这个类的父类是否继承了不允许被继承的类;
   如果这个类不是抽象类,是否实现了其父类或接口中要求实现的所有方法

字节码验证:
  主要工作是进行数据流和控制流分析,保证被校验类的方法在运行时不会做出危害虚拟机安全的行为。
  如果一个类方法体的字节码没有通过字节码验证,那肯定是有问题的;
  但如果一个方法体通过了字
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为什么要学JVM1、一切JAVA代码都运行在JVM之上,只有深入理解虚拟机才能写出更强大的代码,解决更深层次的问题。2、JVM是迈向高级工程师、架构师的必备技能,也是高薪、高职位的不二选择。3、同时,JVM又是各大软件公司笔试、面试的重中之重,据统计,头部的30家互利网公司,均将JVM作为笔试面试的内容之一。4、JVM内容庞大、并且复杂难学,通过视频学习是最快速的学习手段。课程介绍本课程包含11个大章节,总计102课时,无论是笔试、面试,还是日常工作,可以让您游刃有余。第1章 基础入门,从JVM是什么开始讲起,理解JDK、JRE、JVM的关系,java的编译流程和执行流程,让您轻松入门。第2章 字节码文件,深入剖析字节码文件的全部组成结构,以及javap和jbe可视化反解析工具的使用。第3章 类的加载、解释、编译,本章节带你深入理解类加载器的分类、范围、双亲委托策略,自己手写类加载器,理解字节码解释器、即时编译器、混合模式、热点代码检测、分层编译等核心知识。第4章 内存模型,本章节涵盖JVM内存模型的全部内容,程序计数器、虚拟机栈、本地方法栈、方法区、永久代、元空间等全部内容。第5章 对象模型,本章节带你深入理解对象的创建过程、内存分配的方法、让你不再稀里糊涂。第6章 GC基础,本章节是垃圾回收的入门章节,带你了解GC回收的标准是什么,什么是可达性分析、安全点、安全区,四种引用类型的使用和区别等等。第7章 GC算法与收集器,本章节是垃圾回收的重点,掌握各种垃圾回收算法,分代收集策略,7种垃圾回收器的原理和使用,垃圾回收器的组合及分代收集等。第8章 GC日志详解,各种垃圾回收器的日志都是不同的,怎么样读懂各种垃圾回收日志就是本章节的内容。第9章 性能监控与故障排除,本章节实战学习jcmd、jmx、jconsul、jvisualvm、JMC、jps、jstatd、jmap、jstack、jinfo、jprofile、jhat总计12种性能监控和故障排查工具的使用。第10章 阿里巴巴Arthas在线诊断工具,这是一个特别小惊喜,教您怎样使用当前最火热的arthas调优工具,在线诊断各种JVM问题。第11章 故障排除,本章会使用实际案例讲解单点故障、高并发和垃圾回收导致的CPU过高的问题,怎样排查和解决它们。课程资料课程附带配套项目源码2个159页高清PDF理论篇课件1份89页高清PDF实战篇课件1份Unsafe源码PDF课件1份class_stats字段说明PDF文件1份jcmd Thread.print解析说明文件1份JProfiler内存工具说明文件1份字节码可视化解析工具1份GC日志可视化工具1份命令行工具cmder 1份学习方法理论篇部分推荐每天学习2课时,可以在公交地铁上用手机进行学习。实战篇部分推荐对照视频,使用配套源码,一边练习一遍学习。课程内容较多,不要一次性学太多,而是要循序渐进,坚持学习。      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值