深入理解Java虚拟机:JVM高级特性与最佳实践,JVM类加载
在最后一部分,我们解释了类文件。在这一部分,我们将讨论虚拟机如何加载这些类文件。类文件中的信息进入虚拟机后会发生什么变化?这涉及到类加载机制。
类加载机制是将类文件中的类数据加载到内存中,对数据进行检查、转换、解析和初始化,最终形成虚拟机可以直接使用的java类型。这一系列过程都是在程序运行过程中完成的。
类加载器
类别载入器就是下图中的红框。它通过类的完全限定名获得描述类的二进制字节流,从而将java类动态加载到JVM的内存空间中。
如何解决写爬虫IP受阻的问题?立即使用。
适用情景
对于非数组类的加载阶段,可以由系统提供的引导类加载器来完成,也可以由用户自定义的类加载器来完成。
对于数组类,直接由java虚拟机创建,不需要类加载器。
双亲委派机制
家长委托机制是类加载的一种方式。如果一个类装入器收到一个类装入请求,它首先不会尝试自己装入类,而是将请求委托给父类装入器来完成。对于每个级别的类装入器来说都是如此。只有当父加载程序报告它无法完成这个请求时,子加载程序才会尝试自己加载。
类比现实:小明想买个玩具挖掘机,但又不好意思直接开口。于是,就发生了下面的对话。
小明去问爸爸:爸爸,你有挖掘机吗?
爸爸说,没有。
然后爸爸问爷爷:爸爸,爸爸,你有挖掘机吗?
爷爷说,没有。
然后爷爷问大爷爷:爸爸,爸爸,你有挖掘机吗?
爷爷说,我也没有。让曾孙买一个。
结果小明高高兴兴的自己买了个玩具挖掘机。
分类
类加载器是用C实现的,是虚拟机本身的一部分。
其他类加载器都是java语言实现的,独立于虚拟机,都是从抽象类java.lang.ClassLoader继承的
好处
以String类为例。即使用户自己编写了一个String类的实现,在加载这个类的时候,也只会委托给启动类加载器在JDK加载原来的String类,永远不会调用自定义的String类。这确保了系统的安全性。
什么时候进行类加载?
而直接加载类的方法只有以下五种。
(1)当使用new实例化一个对象时;当读取或配置一个类的静态字段时(除了final修饰的静态字段,结果已经在编译时放入常量池);当调用类的静态方法时。
(2)使用java.lang.reflect包的方法对类进行反射调用时。如果该类尚未初始化,您需要首先触发它的初始化。
(3)初始化一个类时,如果发现其父类还没有初始化,需要先触发其父类的初始化。
(4)虚拟机启动时,用户需要指定一个要执行的main类(包含main()方法的类),虚拟机首先初始化这个main类。
类加载过程详述
类加载过程分为五个步骤。大部分都是虚拟机主导和控制的,除了以下两种情况:
在加载阶段
开发人员可以通过定制的类加载器参与进来。
在初始化阶段
将执行开发人员的代码来初始化类变量和其他资源。
1、加载
虚拟机需要完成的任务:
(1)获取二进制字节流,该二进制字节流通过类的完全限定名来定义类。
(2)将这个字节流表示的静态存储结构转换成方法区的运行时数据结构。
(3)在内存中生成一个代表这个类的java.lang.Class对象,作为这个类在方法区的各类数据的访问入口。
2、验证
验证的目的是确保类文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危及虚拟机本身的安全。
分为文件格式验证、元数据验证、字节码验证和符号引用验证四个步骤。其中文件格式验证直接对字节流进行操作,其他三项在方法区进行。
3、准备
这个阶段是正式为类变量分配内存,设置类变量初始值的阶段。它被分配在方法区域中。有两点需要注意:
(1)此时,只有类变量(被static修改的变量)被分配内存,而不是对象变量。当对象被实例化时,分配给对象的内存将随对象一起分配给java堆。
(2)如果一个类变量没有被final修改,那么它的初始值就是数据类型的零值。例如,int类型为0,boolean类型为false。举个例子来说明:
公共静态int值=123;在准备阶段后,初始值是0而不是123,因为此时还没有执行任何java方法,将值赋给123的putstatic指令在程序编译完成后存储在类构造函数的clinit()方法中。因此,将值赋给123的操作将在初始化阶段执行。
public static final int值=123;因为这个时候有final,所以在准备阶段已经把值赋给了123。
4、解析
解析阶段是虚拟机将常量池中的符号引用替换为直接引用的过程。它可以解析类或接口、字段、类方法、接口方法等。
什么是符号引用:
引用是包含关于类、方法名、方法参数等信息的字符串。它可用于在类的方法表中查找相应的方法。
什么是直接引用:
直接引用是偏移量,通过它可以直接在这个类的内存区域找到方法字节码的起始位置。
符号告诉你这个方法的一些特征,你需要通过这些特征找到对应的方法。直接引用就是直接告诉你这个方法在哪里。
5、初始化
这个阶段用来初始化类变量和其他资源,是执行类构造函数的clinit()方法的过程。这时,类中定义的java程序代码才真正开始执行。
以上是JAVA虚拟机类加载机制的详细说明。更多相关问题请访问PHP中文网:JAVA视频教程。以上是JAVA虚拟机(JVM)的详细介绍(5)3354的类加载机制的细节。更多请关注我们的其他相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。