一、类装入基础
存在三种类装入器,分别装入三种不同应用类
引导类装入器
扩展类装入器
系统类装入器
类装入器首先判断要求它装入的类是否与过去装入的类相同。如果相同,就返回上次返回的类(即保存在缓存中的类)。如果不是,就把装入类的机会交给父类。这两步递归地以深度优先的方式重复。如果父类返回 null(或抛出 ClassNotFoundException),那么类装入器会在自己的路径中寻找类的源。
因为父类类装入器总是先得到装入类的机会,所以类装入器装入的类最靠近根。这意味着所有核心引导类都是由引导装入器装入的,这就保证装入了类(例如 java.lang.Object)的正确版本。这也可以让类装入器看到自己或父类或祖先装入的类,但是不能看到子女装入的类。
图 1 显示了三个标准的类装入器:
图 1. 类装入器委托模型
引导类装入器(也称作基本(primordial) 类装入器)不能由 Java 代码实例化。(通常是因为它是作为 VM 本身的一部分实现的。)这个类装入器可以从启动的类路径装入核心系统类,通常是位于 jre/lib 目录的 JAR 文件。但是能用 -Xbootclasspath 命令行选项修改这个类路径。
扩展(extension) 类装入器(也称作标准扩展 类装入器)是引导类装入器的一个孩子。它的主要职责是从扩展目录装入类,通常位于 jre/lib/ext 目录。这提供了简单地访问新扩展的能力,例如不同的安全扩展,不需要修改用户的类路径即可实现。
系统(system) 类装入器(也称作应用程序 类装入器)负责从 CLASSPATH 环境变量指定的路径装入代码。默认情况下,这个类装入器是用户创建的任何类装入器的父类。这也是 ClassLoader.getSystemClassLoader() 方法返回的类装入器。
二、类装入阶段
类的装入实际上可以分成三个阶段:装入、链接和初始化
图 2 显示了这三个阶段:
图 2. 类装入的阶段
装入 阶段包括:找到必要的类(通过查找每个类路径)并装入字节码。在 JVM 中,装入阶段为类对象提供了非常基本的内存结构。在这一阶段不处理方法、字段和引用的其他类。所以,类还不能使用。
链接 是三个阶段中最复杂的一个。可以把它分成三个主要阶段:
• 字节码验证:类装入器对于类的字节码要做许多检测,以确保格式正确、行为正确。
• 类准备:这个阶段准备代表每个类中定义的字段、方法和实现接口所必需的数据结构。
• 解析: 在这个阶段,类装入器装入类所引用的其他所有类。可以用许多方式引用类:
o 超类
o 接口
o 字段
o 方法签名
o 方法中使用的本地变量
初始化 阶段,类中包含的静态初始化器都被执行。在这一阶段末尾,静态字段被初始化成默认值。
在这三个阶段末尾,类被完整地装入,可以使用了。请注意可以用惰性方式执行类装入,所以类装入过程的某些部分可能在第一次使用类的时候才执行,而不是在装入时执行。
显式装入与隐式装入
类装入的方式有两种 —— 显式 或 隐式,两者之间有些细微差异。
显式 类装入发生在使用以下方法调用装入的类的时候:
• cl.loadClass()(cl 是 java.lang.ClassLoader 的实例)
• Class.forName()(启动的类装入器是当前类定义的类装入器)
当调用其中一个方法的时候,指定的类(以类名为参数)由类装入器装入。如果类已经装入,那么只是返回一个引用;否则,装入器会通过委托模型装入类。
隐式 类装入发生在由于引用、实例化或继承导致装入类的时候(不是通过显式方法调用)。在每种情况下,装入都是在幕后启动的,JVM 会解析必要的引用并装入类。与显式类装入一样,如果类已经装入了,那么只是返回一个引用;否则,装入器会通过委托模型装入类。
类的装入通常组合了显式和隐式类装入。例如,类装入器可能先显式地装入一个类,然后再隐式地装入它引用的所有类。
三、查看装入类信息
详细输出
可以用 -verbose 命令行选项打开 JVM 的详细输出。当某些事件发生的时候(例如,类装入时),详细输出会在控制台上显示信息。要想得到额外的类装入信息,可以用详细类输出。可以用 -verbose:class 选项启动这个模式。
解释详细输出
详细输出列出已经打开的所有 JAR 文件,包括到这些 JAR 的完整路径。下面是一个示例:
...
[Opened D:\jre\lib\core.jar]
[Opened D:\jre\lib\graphics.ja]
...
所有装入的类都已经列出,同时还指出它们是从哪个 JAR 文件或目录装入的。例如:
...
[Loaded java.lang.NoClassDefFoundError from D:\jre\lib\core.jar]
[Loaded java.lang.Class from D:\jre\lib\core.jar]
[Loaded java.lang.Object from D:\jre\lib\core.jar]
...
详细类输出显示额外信息,例如在装入超类的时候,在运行静态初始化器的时候。下面是一些示例输出:
...
[Loaded HelloWorld from file:/C:/myclasses/]
[Loading superclass and interfaces of HelloWorld]
[Loaded HelloWorldInterface from file:/C:/myclasses/]
[Loading superclass and interfaces of HelloWorldInterface]
[Preparing HelloWorldInterface]
[Preparing HelloWorld]
[Initializing HelloWorld]
[Running static initializer for HelloWorld]
...
详细输出还显示一些内部抛出的异常(如果发生的话),包含堆栈跟踪。
用 -verbose 解决问题
详细输出有助于解决类路径问题,例如没有打开 JAR 文件(因此不在类路径中)或从错误的位置装入了类。
分享到:
相关推荐
- **WebSphere扩展类装入器**:此扩展类装入器继承了Java的扩展类装入器的功能,但增加了额外的特性以支持WebSphere环境中的高级功能。 - **应用程序和Web模块类装入器**:专门针对部署在WebSphere上的应用程序和Web...
`ClassLoader`是Java运行时系统的一个核心组件,负责查找和装入类文件。 - **`ClassLoader`**:这是Java中的一个抽象类,定义了几个关键的方法来支持类的装载。 - **`loadClass(String name, boolean resolve)`**...
3. **应用程序类装载器(Application Class Loader)**:它是默认的应用程序类装载器,负责加载用户类路径(`java.class.path`)中定义的类。用户可以通过环境变量`CLASSPATH`来控制哪些类路径被包含在内。应用程序类...
Java类加载机制详解 Java类加载机制是Java虚拟机(JVM)中的一种机制,负责将类从字节码文件加载到内存中,并将其转换为可...通过了解类加载机制,我们可以更好地理解Java虚拟机的工作原理,并更好地编写Java程序。
Java运行原理与Java虚拟机(JVM)是Java编程的核心组成部分,它们决定了Java语言的平台无关性和安全性。Java的独特之处在于它的编译和解释过程,它先将源代码编译成字节码,这是一种中间表示,然后通过Java虚拟机...
Java虚拟机类装载 Java虚拟机(JVM)的类装载是指将包含在类文件中的字节码装载到JVM中...了解了JVM中的类装载机制和ClassLoader的工作原理,可以更好地理解Java虚拟机的工作机制,并更好地使用Java语言开发应用程序。
"java执行SQL语句实现查询的通用方法详解" 本文主要介绍了java执行SQL语句实现查询的通用方法详解,具有一定借鉴价值,需要的朋友可以...这些知识点可以帮助开发者更好地理解Java执行SQL语句实现查询的原理和方法。
3. 在首选项窗口中,导航到“Java” → “装入/保存” → “构建路径” → “类路径变量”。 4. 创建一个新的类路径变量,名称为`JADCLIPSE_HOME`,然后将其值设置为`jad.exe`所在的目录(即JDK的`bin`目录)。 5. ...
它负责在运行时查找和装入类文件的类。 1说说JVM原理?内存泄露与溢出区别,何时产生内存泄露? 编译源代码为本地机器码执行。 内存泄露是一部分内存无法回收。溢出是说内存不够用了。泄露可能在将来会导致溢出 ...
日历表格面板 [ConfigLine.java] 控制条类 [RoundBox.java] 限定选择控件 [MonthMaker.java] 月份表算法类 [Pallet.java] 调色板,统一配色类 Java扫雷源码 Java生成自定义控件源代码 2个目标文件 Java实现HTTP连接...
- **类加载器的角色:** 类的装载是由`ClassLoader`及其子类实现的,它们负责在运行时查找并装入类文件。 - **类加载过程:** 类加载的过程包括加载(Loading)、验证(Verification)、准备(Preparation)、解析...
JVM类加载机制负责将Java类装入JVM中执行。这部分内容涉及到类加载过程中的各个步骤,包括加载、验证、准备、解析、初始化等。同时,文档也介绍了类加载器的三个主要类别:启动类加载器、扩展类加载器和应用程序类...
ClassLoader 负责在运行时查找和装入类文件的类。首先,JVM 会检查类文件是否已经被加载,如果没有,则通过 ClassLoader 加载类文件。然后,JVM 会对类文件进行验证、准备、解析和初始化等步骤,最后将类文件加载到...
ClassLoader是JVM的重要组成部分,它负责在运行时查找并装入类文件。类的加载遵循双亲委派模型,即从顶层的Bootstrap ClassLoader开始,向下加载到应用程序的自定义ClassLoader。这个过程确保了类的唯一性和安全性。...
面试中可能会问到关于JVM加载类的原理机制,这涉及到类加载器(ClassLoader),它是Java运行时系统组件,负责查找和装入类文件。ClassLoader采用全盘负责委托机制,保证了类加载的安全性。 此外,Java中的事件委托...
Java最显著的特点是其“一次编译,到处运行”的原理,这得益于Java虚拟机(JVM)。JVM类似于操作系统,它可以在不同的硬件和软件平台上运行,使得Java程序具备了高度的跨平台能力。Java同时兼顾了解释性和编译性语言...