赣州做网站的公司哪家好,莱芜 做网站 公司,简网app工场体验,新网站一天做多少外链什么是类加载每个编写的.java拓展名类文件都存储着需要执行的程序逻辑#xff0c;这些.java文件经过Java编译器编译成拓展名为.class的文件#xff0c;.class文件中保存着Java代码经转换后的虚拟机指令#xff0c;当需要使…什么是类加载每个编写的.java拓展名类文件都存储着需要执行的程序逻辑这些.java文件经过Java编译器编译成拓展名为.class的文件.class文件中保存着Java代码经转换后的虚拟机指令当需要使用某个类时虚拟机将会加载它的.class文件并创建对应的class对象将class文件加载到虚拟机的内存这个过程称为类加载。类加载的生命周期如图所示JVM类加载机制分为五个部分加载验证准备解析初始化。加载加载阶段是类加载过程的第一个阶段。在这个阶段JVM 的主要目的是将字节码从各个位置网络、磁盘等转化为二进制字节流加载到内存中接着会为这个类在 JVM 的方法区创建一个对应的 Class 对象这个 Class 对象就是这个类各种数据的访问入口。验证验证是连接阶段的第一步这一阶段的目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求并且不会危害虚拟机自身的安全。验证阶段大致会完成4个阶段的检验动作文件格式验证验证字节流是否符合Class文件格式的规范例如是否以0xCAFEBABE开头、主次版本号是否在当前虚拟机的处理范围之内、常量池中的常量是否有不被支持的类型。元数据验证对字节码描述的信息进行语义分析注意对比javac编译阶段的语义分析以保证其描述的信息符合Java语言规范的要求例如这个类是否有父类除了java.lang.Object之外。字节码验证通过数据流和控制流分析确定程序语义是合法的、符合逻辑的。符号引用验证确保解析动作能正确执行。验证阶段是非常重要的但不是必须的它对程序运行期没有影响如果所引用的类经过反复验证那么可以考虑采用-Xverifynone参数来关闭大部分的类验证措施以缩短虚拟机类加载的时间。准备重点当完成字节码文件的校验之后JVM 便会开始为类变量分配内存并初始化。这里需要注意两个关键点即内存分配的对象以及初始化的类型。内存分配的对象。Java 中的变量有「类变量」和「类成员变量」两种类型「类变量」指的是被 static 修饰的变量而其他所有类型的变量都属于「类成员变量」。在准备阶段JVM 只会为「类变量」分配内存而不会为「类成员变量」分配内存。「类成员变量」的内存分配需要等到初始化阶段才开始。例如下面的代码在准备阶段只会为 factor 属性分配内存而不会为 website 属性分配内存。public static int factor 3;
public String website www.baidu.com;初始化的类型。在准备阶段JVM 会为类变量分配内存并为其初始化。但是这里的初始化指的是为变量赋予 Java 语言中该数据类型的零值而不是用户代码里初始化的值。例如下面的代码在准备阶段之后sector 的值将是 0而不是 3。public static int sector 3;但如果一个变量是常量被 static final 修饰的话那么在准备阶段属性便会被赋予用户希望的值。例如下面的代码在准备阶段之后number 的值将是 3而不是 0。public static final int number 3;两个语句的区别是一个有 final 关键字修饰另外一个没有。而 final 关键字在 Java 中代表不可改变的意思number 的值一旦赋值就不会在改变了。既然一旦赋值就不会再改变那么就必须一开始就给其赋予用户想要的值因此被 final 修饰的类变量在准备阶段就会被赋予想要的值。而没有被 final 修饰的类变量其可能在初始化阶段或者运行阶段发生变化所以就没有必要在准备阶段对它赋予用户想要的值。解析解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符7类符号引用进行。符号引用简单的理解就是字符串比如引用一个类java.util.ArrayList 这就是一个符号引用字符串引用的对象不一定被加载。直接引用指针或者地址偏移量。引用对象一定在内存已经加载。初始化初始化这个阶段就是执行类构造器 clinit ()方法的过程为类的静态变量赋予正确的初始值JVM负责对类进行初始化主要对类变量进行初始化。在Java中对类变量进行初始值设定有两种方式①声明类变量是指定初始值②使用静态代码块为类变量指定初始值JVM初始化步骤1、假如这个类还没有被加载和连接则程序先加载并连接该类2、假如该类的直接父类还没有被初始化则先初始化其直接父类3、假如类中有初始化语句则系统依次执行这些初始化语句类初始化时机只有当对类的主动使用的时候才会导致类的初始化类的主动使用包括以下六种创建类的实例也就是new的方式访问某个类或接口的静态变量或者对该静态变量赋值调用类的静态方法反射如Class.forName(“com.shengsiyuan.Test”)初始化某个类的子类则其父类也会被初始化Java虚拟机启动时被标明为启动类的类Java Test直接使用java.exe命令来运行某个主类使用当 JVM 完成初始化阶段之后JVM 便开始从入口方法开始执行用户的程序代码。卸载当用户程序代码执行完毕后JVM 便开始销毁创建的 Class 对象最后负责运行的 JVM 也退出内存。类加载器顾名思义类加载器class loader用来加载 Java 类到 Java 虚拟机中。JVM提供了3种类加载器启动类加载器Bootstrap ClassLoader负责加载存放在JDKjrelib(JDK代表JDK的安装目录下同)下或被-Xbootclasspath参数指定的路径中的并且能被虚拟机识别的类库如rt.jar所有的java.开头的类均被Bootstrap ClassLoader加载。启动类加载器是无法被Java程序直接引用的。扩展类加载器Extension ClassLoader该加载器由sun.misc.Launcher$ExtClassLoader实现它负责加载JDKjrelibext目录中或者由java.ext.dirs系统变量指定的路径中的所有类库如javax.开头的类开发者可以直接使用扩展类加载器。应用程序类加载器Application ClassLoader该类加载器由sun.misc.Launcher$AppClassLoader来实现它负责加载用户类路径ClassPath所指定的类开发者可以直接使用该类加载器如果应用程序中没有自定义过自己的类加载器一般情况下这个就是程序中默认的类加载器。应用程序都是由这三种类加载器互相配合进行加载的如果有必要我们还可以加入自定义的类加载器。双亲委派模型下图中展示了类加载器直接的关系和双亲委派模型从图中我们发现除启动类加载器外每个加载器都有父的类加载器。双亲委派机制如果一个类加载器在接到加载类的请求时它首先不会自己尝试去加载这个类而是把这个请求任务委托给父类加载器去完成依次递归如果父类加载器可以完成类加载任务就成功返回只有父类加载器无法完成此加载任务时才自己去加载。从类的继承关系来看ExtClassLoader和AppClassLoader都是继承URLClassLoader都是ClassLoader的子类。而BootStrapClassLoader是有C写的不再java的ClassLoader子类中。从图中可以看到类加载器间的父子关系不是以继承的方式实现的而是以组合关系的方式来复用父加载器的代码。如果一个类加载器收到了类加载的请求它首先会把这个请求委派给父加载器去完成每一个层次的类加载器都是如此。 双亲委派模型的好处 Java类随着加载它的类加载器一起具备了一种带有优先级的层次关系。比如Java中的Object类它存放在rt.jar之中,无论哪一个类加载器要加载这个类最终都是委派给处于模型最顶端的启动类加载器进行加载因此Object在各种类加载环境中都是同一个类。如果不采用双亲委派模型那么由各个类加载器自己取加载的话那么系统中会存在多种不同的Object类。jvm类加载相关链接https://blog.csdn.net/javazejian/article/details/73413292https://www.jianshu.com/p/3cab74a189dehttps://www.fangzhipeng.com/javainterview/2019/04/15/class-loader.htmlhttp://www.ityouknow.com/jvm/2017/08/19/class-loading-principle.htmlhttps://www.cnblogs.com/chanshuyi/p/the_java_class_load_mechamism.htmlhttps://www.ibm.com/developerworks/cn/java/j-lo-classloader/index.html