Java的类加载器

Java的类加载机制

每一个Java程序对应都对应一个jvm虚拟机,当程序结束的时候jvm也就对应的结束了。

Java虚拟机中的类加载器分为两种:原始类加载器(primordial class loader)和类加载器对象(class loader objects)。原始类加载器是Java虚拟机实现的一部分,类加载器对象是运行中的程序的一部分。不同类加载器加载的类被不同的命名空间所分割。

类加载流程:
  1. 加载、连接、初始化(Loading, Linking and Initialization)
类加载子系统不仅仅负责定位并加载类文件,他按照以下严格的步骤作了很多其他的事情:
   1)、加载:寻找并导入指定类型(类和接口)的二进制信息
   2)、连接:进行验证、准备和解析
    ①验证:确保导入类型的正确性
    ②准备:为类型分配内存并初始化为默认值
    ③解析:将字符引用解析为直接饮用
   3)、初始化:调用Java代码,初始化类变量为合适的值 
  2、原始类加载器(The Primordial Class Loader)
   每个Java虚拟机都必须实现一个原始类加载器,他能够加载那些遵守类文件格式并且被信任的类。但是,Java虚拟机的规范并没有定义如何加载类,这由 Java虚拟机实现者自己决定。对于给定类型名的类型,原始莱加载器必须找到那个类型名加“.class”的文件并加载入虚拟机中。
  3、类加载器对象
  虽然类加载器对象是Java程序的一部分,但是ClassLoader类中的三个方法可以访问Java虚拟机中的类加载子系统。
  1)、protected final Class defineClass(…):使用这个方法可以出入一个字节数组,定义一个新的类型。
  2)、protected Class findSystemClass(String name):加载指定的类,如果已经加载,就直接返回。
  3)、protected final void resolveClass(Class c):defineClass()方法只是加载一个类,这个方法负责后续的动态连接和初始化。
 4、命名空间
  当多个类加载器加载了同一个类时,为了保证他们名字的唯一性,需要在类名前加上加载该类的类加载器的标识。
  这里写图片描述
  我个人认为类加载的过程可以理解为程序运行的驱动的加载,相当于汽车的驱动,在引擎提供动力依次传输到轴承、传动系统等等,反正能跑起来了。而与之对应的还有一个类检查机制,当车不能走的时候,我们肯定是先检查最外面的,看电源启动了么、轮子能转么、总不能先拆发动机看看,最后发现没毛病,回头才发现没有插车钥匙。

类的双亲委派机制

JVM在加载类时默认采用的是双亲委派机制。通俗的讲,就是某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。
  Java的类非常的懒,只要他的父类有,他就不自己执行。
####类的执行机制
  JVM是基于栈的体系结构来执行class字节码的。线程创建后,都会产生程序计数器(PC)和栈(Stack),程序计数器存放下一条要执行的指令在方法内的偏移量,栈中存放一个个栈帧,每个栈帧对应着每个方法的每次调用,而栈帧又是有局部变量区和操作数栈两部分组成,局部变量区用于存放方法中的局部变量和参数,操作数栈中用于存放方法执行过程中产生的中间结果。
(涉及到JVM的物理结构,及数据存储结构)
这里写图片描述
  既然看到这里了,我们再看看jvm的基本结构吧!

Java平台的逻辑结构

这里写图片描述
jvm的自身逻辑结构:
这里写图片描述
  从上面的图看出:
  JVM内存结构主要包括两个子系统和两个组件。两个子系统分别是Classloader子系统和Executionengine(执行引擎)子系统;两个组件分别是Runtimedataarea(运行时数据区域)组件和Nativeinterface(本地接口)组件。
  Classloader子系统的作用:
  根据给定的全限定名类名(如java.lang.Object)来装载class文件的内容到  Runtimedataarea中的methodarea(方法区域)。Java程序员可extendsjava.lang.ClassLoader类来写自己的Classloader。
  Executionengine子系统的作用:
  执行classes中的指令。任何JVMspecification实现(JDK)的核心都是Executionengine,不同的JDK例如Sun的JDK和IBM的JDK好坏主要就取决于他们各自实现的Executionengine的好坏。
  Nativeinterface组件:
  与nativelibraries交互,是其它编程语言交互的接口。当调用native方法的时候,就进入了一个全新的并且不再受虚拟机限制的世界,所以也很容易出现JVM无法控制的nativeheapOutOfMemory。
  RuntimeDataArea组件:
  这就是我们常说的JVM的内存了。它主要分为五个部分——
    1、Heap(堆):一个Java虚拟实例中只存在一个堆空间
    2、MethodArea(方法区域):被装载的class的信息存储在Methodarea的内存中。当虚拟机装载某个类型时,它使用类装载器定位相应的class文件,然后读入这个class文件内容并把它传输到虚拟机中。
    3、JavaStack(java的栈):虚拟机只会直接对Javastack执行两种操作:以帧为单位的压栈或出栈
    4、ProgramCounter(程序计数器):每一个线程都有它自己的PC寄存器,也是该线程启动时创建的。PC寄存器的内容总是指向下一条将被执行指令的饿地址,这里的地址可以是一个本地指针,也可以是在方法区中相对应于该方法起始指令的偏移量。
    5、Nativemethodstack(本地方法栈):保存native方法进入区域的地址。
  这些就是jvm的基本结构,也是整个类加载机制所要求的。

希望大神指正

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值