JVM类加载机制

简介: JVM类加载机制

一、类加载步骤

 

JVM采用的是懒加载机制,即只有类在被使用时才加载。类的加载主要可分为以下几步:

加载:即把类字节码文件加载到内存,在一步会在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

验证:校验字节码文件的准确性,每个字节码文件都有固定的格式,以此来校验字节码文件是否被损坏。

准备:给静态变量分配内存空间并赋与默认值。

解析:符号引用替换为直接引用,该阶段会把一些静态方法(符号引用,比如 main()方法)替换为指向数据所在内存的指针或句柄等(直接引用),这是所谓的静态链接过程(类加载期间完成),动态链接是在程序运行期间完成的将符号引用替换为直接引用。

初始化:对类变量初始化赋值,并执行静态代码块。

二、类加载器

JVM的类加载主要有四类加载器来配合完成。

引导类加载器(BootstrapClassLoad):负责加载支撑JVM运行的位于JRE的lib目录下的核心类库,比如 rt.jar、charsets.jar等。为避免核心类库被篡改,这类核心类库只能有引导类加载器加载,即使自定义类加载指定去加载该路径下的类也会报错无法加载成功。引导类加载器由C++代码实现,因此,在JAVA程序中对它的引用值为null。

扩展类加载器(ExtClassLoad):负责加载支撑JVM运行的位于JRE的lib目录下的ext扩展目录中的JAR类包。

应用程序类加载器(AppClassLoad):负责加载ClassPath路径下的类包,主要就是加载你自己写的那些类。

自定义加载器:负责加载用户自定义路径下的类包。自定义加载器需要继承ClassLoad类,同时,可根据自身业务需要是否要重新其加载类的loadClass和findClass方法。

类加载器从上往下构成"父子关系",注意,是在加载器类中有一个parent属性的值为上一层类加载器对象,并非JAVA层面的类继承关系。

三、类加载机制

JVM的类加载机制采用的是双亲委派机制,当加载一个类时,如果使用自定义类加载器,则从自定义加载器查看该加载器是否加载过此类,如果没有则委托上层的应用程序类加载器去加载,在加载时,同样的检查当前类加载器是否加载过此类,如果没有则委托上层的扩展类加载器去加载。在加载时,同样的检查当前类加载器是否加载过此类,没有则委托上层的引导类加载器去加载,在加载时,同样的检查当前类加载器是否加载过此类,如果没有,则由引导类加载器去加载此类,如果在引导类加载器管辖的路径下没加载到此类,则有下层的扩展类程序类加载器去加载,如果在扩展类加载器管辖的路径下没加载到此类,则有下层的应用程序类加载器去加载;如果在应用程序类加载器管辖的路径下没加载到此类,则有下层的自定义类加载器去加载;再加载不到则抛出异常。可以总结成一句话:从下往上检查类是否被加载过,从上往下去加载类。

四、双亲委派机制的意义

   沙箱安全机制:各个类加载器管辖自己路径下类的加载,比如核心类库只能有引导类加载器加载,可以防止核心类库被篡改。自己写一个跟核心类库一模一样类名、包名的Object、String类,是不会被加载成功的。

   避免类的重复加载:当父亲已经加载了该类时,就没有必要子ClassLoader再加载一 次,保证被加载类的唯一性。

   提升类加载效率:因为在应用程序中,90%以上的类都是程序员自己写的类,所以从下往上开始检查能提升类加载的效率。

五、全盘负责委托机制

全盘负责 ”是指当一个 ClassLoder 装载一个类时,除非显示的使用另外一个 ClassLoder ,该类

所依赖及引用的类也由这个 ClassLoder作为入口 载入,由它来触发类加载。

六、Tomcat打破双亲委派机制

 tomcat为什么不用双亲委派机制?

   一个tomcat可能运行多个应用程序,而且这个多个应用程序引用了同一个类的不同版本,所以,从双亲委派机制保证类只加载一份的特点不符合tomcat的业务场景需求。

 tomcat如何保证jps的热加载?  

  每个jsp文件对应一个唯一的类加载器,当一个jsp文件修改了,就直接卸载这个jsp类加载器。重新创建类加载器,重新加载jsp文件

  tomcat的几个主要类加载器:

commonLoader:Tomcat最基本的类加载器,加载路径中的class可以被Tomcat容器本身以及各个Webapp访问;

catalinaLoader:Tomcat容器私有的类加载器,加载路径中的class对于Webapp不 可见;

sharedLoader:各个Webapp共享的类加载器,加载路径中的class对于所有Webapp可见,但是对于Tomcat容器不可见;

WebappClassLoader:各个Webapp私有的类加载器,加载路径中的class只对当前 Webapp可见,比如加载war包里相关的类,每个war包应用都有自己的WebappClassLoader,实现相互隔离,比如不同war包应用引入了不同的spring版本, 这样实现就能加载各自的spring版本;

注意: 同一个JVM内,两个相同包名和类名的类对象可以共存,因为他们的类加载器可以不一样(同一个类加载器Class,两个类加载器实例也称为不一样),所以看两个类对象是否是同一个,除了看类的包名和类名是否都相同之外,还需要他们的类加载器对象也是同一个才能认为他们是同一个。

相关文章
|
4月前
|
安全 Java
对 JVM 的类加载机制以及寻找字节码文件的“双亲委派模型”的理解
对 JVM 的类加载机制以及寻找字节码文件的“双亲委派模型”的理解
31 0
|
4月前
|
安全 前端开发 Java
JDK源码级别彻底剖析JVM类加载机制
JDK源码级别彻底剖析JVM类加载机制
|
20天前
|
数据库 C# 开发者
WPF开发者必读:揭秘ADO.NET与Entity Framework数据库交互秘籍,轻松实现企业级应用!
【8月更文挑战第31天】在现代软件开发中,WPF 与数据库的交互对于构建企业级应用至关重要。本文介绍了如何利用 ADO.NET 和 Entity Framework 在 WPF 应用中访问和操作数据库。ADO.NET 是 .NET Framework 中用于访问各类数据库(如 SQL Server、MySQL 等)的类库;Entity Framework 则是一种 ORM 框架,支持面向对象的数据操作。文章通过示例展示了如何在 WPF 应用中集成这两种技术,提高开发效率。
36 0
|
26天前
|
安全 前端开发 Java
【JVM 探秘】ClassLoader 类加载器:揭秘 Java 类加载机制背后的秘密武器!
【8月更文挑战第25天】本文全面介绍了Java虚拟机(JVM)中的类加载器,它是JVM的核心组件之一,负责将Java类加载到运行环境中。文章首先概述了类加载器的基本工作原理及其遵循的双亲委派模型,确保了核心类库的安全与稳定。接着详细阐述了启动、扩展和应用三种主要类加载器的层次结构。并通过一个自定义类加载器的例子展示了如何从特定目录加载类。此外,还介绍了类加载器的完整生命周期,包括加载、链接和初始化三个阶段。最后强调了类加载器在版本隔离、安全性和灵活性方面的重要作用。深入理解类加载器对于掌握JVM内部机制至关重要。
41 0
|
4月前
|
前端开发 Java 数据库连接
JVM(类加载机制)
JVM(类加载机制)
52 4
|
4月前
|
存储 缓存 安全
深入浅出JVM(三)之HotSpot虚拟机类加载机制
深入浅出JVM(三)之HotSpot虚拟机类加载机制
|
存储 算法 Java
Android 面试必备 - JVM 及 类加载机制
Android 面试必备 - JVM 及 类加载机制
|
4月前
|
前端开发 Java
深入理解Java虚拟机:类加载机制
【2月更文挑战第23天】本文深入探讨了Java虚拟机(JVM)的类加载机制,包括类加载器的层次结构、类加载的过程以及双亲委派模型。通过对JVM类加载机制的理解,可以帮助我们编写更高效的Java代码。
|
11月前
|
存储 安全 前端开发
JVM 类加载机制
JVM 类加载机制
39 0
|
11月前
|
前端开发 安全 Java
JVM第二讲:类加载机制
JVM第二讲:类加载机制