国内大一html网站简单设计,汽车之家网页版地址,免费ppt资源网站,好的产品怎么推广语言本篇内容包括#xff1a;Java 类的加载机制#xff08;Jvm 结构组成、Java 类的加载#xff09;、类的生命周期#xff08;加载-验证-准备-解析-初始化-使用-卸载#xff09;、类加载器 以及 双亲委派模型。 一、Java 类的加载机制
1、 Jvm 结构组成
Jvm 整体组成可分为… 本篇内容包括Java 类的加载机制Jvm 结构组成、Java 类的加载、类的生命周期加载-验证-准备-解析-初始化-使用-卸载、类加载器 以及 双亲委派模型。 一、Java 类的加载机制
1、 Jvm 结构组成
Jvm 整体组成可分为四个部分类加载器、运行时数据区Runtime Data Area、执行引擎Execution Engine、本地库接口Native Interface
类加载器负责从字节码Class文件中加载 class 信息到运行时数据区的方法区运行时数据区存放 Jvm 在执行 Java 程序时相关数据的区域执行引擎将字节码翻译成底层系统指令再交由 CPU 去执行本地库接口执行过程中可能需要调用到其他语言比如 C 语言的本地接口。
PSJavac 是收录于 Jdk 中的 Java 语言编译器。该工具可以将后缀名为 .java 的源文件编译为后缀名为 .class 的可以运行于 Java 虚拟机的字节码。
程序在被执行之前 Java 代码会被先转换成字节码.class 文件 Jvm 首先通过一定的方式类加载器①ClassLoader把字节码文件加载到内存中运行时数据区②Runtime Data Area而字节码文件是 Jvm 提供的一套指令集规范并不能直接交个底层操作系统去执行因此需要特定的命令解析器执行引擎③Execution Engine将字节码翻译成底层系统指令再交由 CPU 去执行而这个过程中需要调用其他语言的接口本地库接口④Native Interface来实现整个程序的功能这就是这 4 个主要组成部分的职责与功能。 而我们通常所说的 Jvm 组成指的是运行时数据区因为通常需要程序员调试分析的区域就是运行时数据区或者更具体的来说就是运行时数据区里面的堆Heap模块
2、Java 类的加载
类的加载指的是将类的 .class 文件中的二进制数据读入到内存中将其放在运行时数据区的方法区内然后在堆区创建一个 java.lang.Class 对象用来封装类在方法区内的数据结构。类的加载的最终产品是位于堆区中的 Class 对象Class 对象封装了类在方法区内的数据结构并且向 Java 程序员提供了访问方法区内的数据结构的接口。
类加载器并不需要等到某个类被首次主动使用时再加载它 Jvm 规范允许类加载器在预料某个类将要被使用时就预先加载它如果在预先加载的过程中遇到了 .class 文件缺失或存在错误类加载器必须在程序首次主动使用该类时才报告错误 LinkageError 错误如果这个类一直没有被程序主动使用那么类加载器就不会报告错误。
加载.class 文件的方式:
从本地系统中直接加载通过网络下载 .class 文件从 zip、jar 等归档文件中加载 .class 文件从专有数据库中提取 .class 文件将 Java 源文件动态编译为 .class 文件由其他文件生成 二、Java 类的生命周期
类从被加载到 Jvm 内存中开始到卸载出内存为止生命周期分为7个阶段加载-验证-准备-解析-初始化-使用-卸载。或分为5个阶段把 验证-准备-解析 分为连接阶段 1、加载
加载过程就是把 class 字节码文件载入到虚拟机中至于从哪儿加载虚拟机设计者并没有限定你可以从文件、压缩包、网络、数据库等等地方加载 class 字节码。
通过一个类的全限定名来获取其定义的二进制字节流将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构在Java堆中生成一个代表这个类的 java.lang.Class 对象作为对方法区中这些数据的访问入口
2、验证连接阶段的第一步确保被加载的类的正确性
这一阶段的目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求并且不会危害虚拟机自身的安全。验证阶段大致会完成4个阶段的检验动作文件格式验证、元数据验证、字节码验证、符号引用验证
验证阶段是非常重要的但不是必须的它对程序运行期没有影响如果所引用的类经过反复验证那么可以考虑采用 -Xverifynone 参数来关闭大部分的类验证措施以缩短虚拟机类加载的时间。
3、准备连接阶段的第二步为类的静态变量分配内存并将其初始化为默认值
准备阶段的工作就是为类的静态变量分配内存并设为 Jvm 默认的初值对于非静态的变量则不会为它们分配内存。静态变量的初值为 Jvm 默认的初值而不是我们在程序中设定的初值。仅包含类变不包含实例变量
4、解析连接阶段的第三步把类中的符号引用转换为直接引用
解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符7类符号引用进行。符号引用就是一组符号来描述目标可以是任何字面量。
直接引用就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄。
5、初始化为类的静态变量赋予正确的初始值
主要对类变量进行初始化。在Java中对类变量进行初始值设定有两种方式
声明类变量是指定初始值使用静态代码块为类变量指定初始值
Jvm初始化步骤 假如这个类还没有被加载和连接则程序先加载并连接该类 假如该类的直接父类还没有被初始化则先初始化其直接父类 假如类中有初始化语句则系统依次执行这些初始化语句
类初始化时机只有当对类的主动使用的时候才会导致类的初始化类的主动使用包括以下六种
创建类的实例也就是new的方式访问某个类或接口的静态变量或者对该静态变量赋值调用类的静态方法反射如 Class.forName(“com.shengsiyuan.Test”) 初始化某个类的子类则其父类也会被初始化Java虚拟机启动时被标明为启动类的类 JavaTest 直接使用 java.exe 命令来运行某个主类 三、类加载器
类加载器是负责将可能是网络上、也可能是磁盘上的 .class 文件加载到内存中。并为其生成对应的 java.lang.Class 对象。一旦一个类被载入 Jvm 了同一个类就不会被再次加载。那么怎样才算是同一个类在 Java 中一个类用其全限定类名包名和类名作为其唯一标识但是在 Jvm 中一个类用其全限定类名和其类加载器作为其唯一标识。也就是说在 Java 中的同一个类如果用不同的类加载器加载则生成的 .class 对象认为是不同的。
当 Jvm启动时会形成由三个类加载器组成的初始类加载器层次结构:
启动类加载器Bootstrap ClassLoader是嵌在 Jvm 内核中的加载器该加载器是用 C 语言写的主要负载加载 JAVA_HOME/lib 下的类库启动类加载器无法被应用程序直接使用扩展类加载器Extension ClassLoader该加载器器是用JAVA编写且它的父类加载器是 Bootstrap是由 sun.misc.Launcher$ExtClassLoader实现的主要加载 JAVA_HOME/lib/ext 目录中的类库。开发者可以这几使用扩展类加载器系统类加载器App ClassLoader也称为应用程序类加载器负责加载应用程序 classpath 目录下的所有 .jar 和 .class 文件。它的父加载器为 Extension ClassLoader。
上述三种类加载器的层次关系如下 Ps类加载器的体系并不是“继承”体系而是委派体系大多数类加载器首先会到自己的 parent 中查找类或者资源如果找不到才会到自己本地查找。类加载器的委托行为动机是为了避免相同的类被加载多次。 五、双亲委派模型
1、双亲委派模型
如果以上三种类加载器不能满足要求的话程序员还可以自定义类加载器继承 java.lang.ClassLoader 类
它们的层级关系即 自定义类加载器 - 应用程序加载器 - 扩展加载器 - 启动类加载器这种层次关系被称作为双亲委派模型如果一个类加载器收到了加载类的请求它会先把请求委托给上层加载器去完成上层加载器又会委托上上层加载器一直到最顶层的类加载器如果上层加载器无法完成类的加载工作时当前类加载器才会尝试自己去加载这个类。 2、双亲委派模式优势
采用双亲委派模式的是好处是 Java 类随着它的类加载器一起具备了一种带有先级的层次关系通过这种层级关可以避免类的重复加载当父亲已经加载了该类时就没有必要子 ClassLoader 再加载一次其次是考虑到安全因素Java 核心 api 中定义类型不会被随意替换假设通过网络传递一个名为 java.lang.Integer 的类通过双亲委托模式传递到启动类加载器而启动类加载器在核心 Java API 发现这个名字的类发现该类已被加载并不会重新加载网络传递的过来的 java.lang.Integer而直接返回已加载过的 Integer.class这样便可以防止核心 API 库被随意篡改可能你会想如果我们在 classpath 路径下自定义一个名为 java.lang.SingleInterge 类呢该类并不存在 java.lang 中经过双亲委托模式传递到启动类加载器中由于父类加载器路径下并没有该类所以不会加载将反向委托给子类加载器加载最终会通过系统类加载器加载该类。但是这样做是不允许因为 java.lang 是核心 API 包需要访问权限强制加载将会报出异常 java.lang.SecurityException: Prohibited package name: java.lang 所以无论如何都无法加载成功的。