java面试-- 必问之jvm与性能优化(一)
类加载器(ClassLoader)是Java运行时环境(JRE)中负责动态加载Java类到JVM内存的重要组件。它是Java核心类库java.lang中的一个重要类。类加载器的主要职责是根据一个类的全名(包括包名)来查找或加载这个类的.class文件,并将其加载到Java虚拟机中,形成对应的Class对象。类加载器在Java中扮演了非常重要的角色,它是实现Java动态性的关键机制之一。通过类加载器
问题一、 描述一下 JVM 加载 Class 文件的原理机制?
JVM(Java虚拟机)加载Class文件的原理机制是Java程序运行的关键组成部分。这一过程涉及到多个阶段,确保Java程序能够跨平台运行,并动态地加载、解析和执行Java Class文件。以下是JVM加载Class文件的主要步骤和原理:
1. 类加载:
- JVM首先通过类加载器(ClassLoader)将Java类加载到内存中。类加载器负责从文件系统、JAR包或其他地方查找和加载所需的class文件。
- Java虚拟机规范定义了三种主要的类加载器:启动类加载器(Bootstrap
ClassLoader)、扩展类加载器(Extension ClassLoader)和系统类加载器(System
ClassLoader)。 - 类加载器可以根据类的全名加载Java类,但需要注意的是,对于同一个类名,不同的类加载器可能会加载不同的类。
2. 加载阶段:
-
在加载阶段,JVM主要完成三件事情:通过全类名获取定义此类的二进制字节流;将字节流所代表的静态存储结构转换为方法区的运行时数据结构;在内存中生成一个代表该类的Class对象,作为方法区这些数据的访问入口。
-
获取二进制字节流的方式非常灵活,可以从本地系统、ZIP包、网络、动态代理技术运行时动态生成、其他文件(如JSP)或数据库中获取。
3. 链接阶段:
- 链接阶段包括验证、准备和解析三个子阶段。验证确保被加载的类信息符合JVM规范,没有安全方面的问题;准备为类的静态变量分配内存,并将其初始化为默认值;解析则是把类中的符号引用转换为直接引用。
4. 初始化阶段:
- 在初始化阶段,JVM为类的静态变量赋予正确的初始值,执行类构造器方法()中的代码。
值得注意的是,这些阶段通常不是按顺序进行或完成的,而是互相交叉地混合进行的。例如,在加载阶段可能会调用或激活其他阶段。
JVM通过这一系列的步骤和机制,实现了对Java Class文件的动态加载和执行,为Java程序的跨平台运行提供了坚实的基础。同时,类加载器和双亲委派模型等机制确保了类的加载过程的安全性和一致性。
问题二、 什么是类加载器?
类加载器(ClassLoader)是Java运行时环境(JRE)中负责动态加载Java类到JVM内存的重要组件。它是Java核心类库java.lang中的一个重要类。类加载器的主要职责是根据一个类的全名(包括包名)来查找或加载这个类的.class文件,并将其加载到Java虚拟机中,形成对应的Class对象。
类加载器在Java中扮演了非常重要的角色,它是实现Java动态性的关键机制之一。通过类加载器,Java应用程序可以在运行时动态地加载和卸载类,从而实现插件式架构、热部署等高级功能。
问题三、 类加载器有哪些?
在Java中,类加载器(ClassLoader)是用于动态加载Java类的关键组件。Java提供了几种不同类型的类加载器,它们共同构成了Java的类加载机制。以下是Java中常见的类加载器类型:
1. 启动类加载器(Bootstrap ClassLoader):
- 也称为原始类加载器,是JVM自身的一部分。
- 主要负责加载Java的核心类库,如java.lang.*等。
- 它不是java.lang.ClassLoader的子类,而是由JVM的启动机制来初始化。
- 加载扩展类和应用程序类加载器,并指定它们的父加载器。
2. 扩展类加载器(Extension ClassLoader):
- 由 sun.misc.Launcher$ExtClassLoader 实现。
- 负责加载Java的扩展目录(通常是$JAVA_HOME/lib/ext目录)中的类库。
- 它是启动类加载器的子加载器。
3. 系统类加载器(System ClassLoader):
- 也称为应用类加载器(Application ClassLoader)。
- 由sun.misc.Launcher$AppClassLoader实现。
- 负责加载应用程序的类路径(classpath)上指定的类。
- 它是扩展类加载器的子加载器,并且是大多数应用程序默认的类加载器。
4. 自定义类加载器:
- 通过继承 java.lang.ClassLoader 类,开发者可以创建自己的类加载器。
- 自定义类加载器可以用于实现特定的类加载逻辑,如从网络加载类、从数据库中加载类、实现类的加密和解密等。
- 自定义类加载器在热部署、代码隔离、插件系统等场景中非常有用。
在Java的类加载机制中,类加载器之间通常遵循双亲委派模型(Parent Delegation Model)。当一个类加载器需要加载一个类时,它首先会把这个请求委派给父类加载器去完成,每一层的类加载器都是如此。只有当父类加载器无法完成这个加载请求时,子加载器才会尝试自己去加载。这种机制确保了Java核心类库的安全性和稳定性。
问题四、什么是tomcat类加载机制?
Tomcat类加载机制是指Tomcat服务器在运行时如何加载Java类的过程。Tomcat使用了一种特定的类加载器层次结构来确保Web应用程序的类能够正确、安全地加载。
Tomcat的类加载器层次主要包括以下几个部分:
1. Bootstrap类加载器:
- 这是JVM自带的类加载器,主要负责加载Java的核心类库,如java.lang.*等。
- 位于jre/lib/ext下。
2. System类加载器:
也称为扩展类加载器,负责加载Tomcat自身的类库,如bootstrap.jar等。这些类库通常位于Tomcat安装目录下的lib或bin文件夹中。
3. Common类加载器:
这个类加载器负责加载Tomcat服务器以及所有Web应用程序共享的类库。这些类库通常位于Tomcat的lib目录下。
4. Web应用程序类加载器:
每个在Tomcat中部署的Web应用程序都有自己的类加载器。这个类加载器负责加载该应用程序特定的类库,这些类库通常位于Web应用程序的WEB-INF/lib目录下,以及WEB-INF/classes目录下的类文件。
当应用需要到某个类时,则会按照下面的顺序进行类加载:
1 使用bootstrap引导类加载器加载
2 使用system系统类加载器加载
3 使用应用类加载器在WEB-INF/classes中加载
4 使用应用类加载器在WEB-INF/lib中加载
5 使用common类加载器在CATALINA_HOME/lib中加载
问题五、简单描述Java 类加载过程?
java类加载过程是指JVM将类的.class文件中的字节码装载到内存中,并进行验证、准备、解析和初始化等一系列步骤的过程。这个过程由类加载器负责执行,确保了Java程序的正常运行。
以下是Java类加载过程的主要步骤:
1. 加载(Loading):
类加载器通过类的全名获取定义此类的二进制字节流。这些字节流通常来自.class文件,但也可以从网络、数据库或其他来源获取。
加载阶段会将字节流转换为JVM内部的数据结构,并生成一个代表该类的Class对象,作为方法区这些数据的访问入口。
2. 验证(Verification):
在连接阶段,JVM会对加载的类进行验证,以确保其符合Java虚拟机规范,没有安全问题。
验证过程会检查类的格式、语义和操作码等,防止恶意代码的执行。
3. 准备(Preparation):
准备阶段为类的静态变量分配内存,并赋予默认值。
注意,此时不会实际初始化静态变量,只是为其分配内存空间。
4. 解析(Resolution):
解析阶段是将常量池内的符号引用替换为直接引用的过程。
这使得后续可以直接通过内存地址或偏移量进行访问,提高了效率。
5. 初始化(Initialization):
初始化阶段是类加载过程的最后一步,它执行类的静态初始化代码和初始化静态变量。
静态初始化代码通常位于静态块中,它们会在类首次被主动使用时执行。
JVM会确保在多线程环境下,类的初始化过程只会被一个线程执行。
在整个类加载过程中,类加载器起着关键作用。JVM提供了三种主要的类加载器:启动类加载器、扩展类加载器和系统类加载器。这些加载器遵循双亲委派模型,即当一个类加载器需要加载一个类时,它会首先将这个请求委派给它的父类加载器去完成。这种机制有助于保证Java核心类库的安全性和一致性。
更多推荐
所有评论(0)