各位读者好! 在JVM系列的上一篇文章中,开发人员了解了Java虚拟机(JVM)及其体系结构。 本教程将帮助开发人员正确回答以下主题的问题:
ClassLoader
子系统 运行时数据区
1.简介
在继续之前,让我们看一下Java虚拟机及其基本特征。
1.1什么是Java虚拟机(JVM)?
Java虚拟机(JVM)是驻留在您的计算机上的抽象虚拟机,并为Java字节码提供了运行时环境以供执行。 JVM可用于许多硬件和软件平台,但是很少有Java开发人员知道Java运行时环境(JRE)是Java虚拟机(JVM)的实现。 JVM分析字节码,对其进行解释,然后执行相同的字节码以显示输出。
JVM的基本功能是执行已编译的.class
文件(即字节码)并生成输出。请注意,每个操作系统都有一个不同的JVM,但是在所有操作系统上生成的字节码输出都是相同的。 这意味着在Windows操作系统上生成的字节码也可以在Linux操作系统上运行,反之亦然,从而使Java成为独立于平台的语言。
图1:Java虚拟机概述
1.1.1 JVM做什么?
Java虚拟机执行以下操作:
加载所需的.class
和jar文件 分配参考并验证代码 执行代码 为Java字节码提供运行时环境
1.1.2 JVM内部架构
下图显示了符合JVM规范的Java虚拟机的关键内部组件。
图2:Java虚拟机架构
下面分别解释图2中所示的类加载器和运行时数据区域组件。
1.2 ClassLoader子系统
类加载器子系统是Java虚拟机的基本核心,用于加载/读取.class
文件并将字节码保存在JVM方法区域中。 该子系统处理动态类加载功能,并执行三个主要功能,即:
加载:此组件处理将.class
文件从硬件系统加载到JVM内存并存储二进制数据(例如完全限定的类名,直接父类名,有关方法,变量,构造函数的信息等)。在方法领域。 对于每个已加载的.class
文件,JVM会立即在堆存储器上创建一个类型为java.lang.class
的对象。请记住,即使开发人员多次调用一个类,也只会创建一个类对象。 类加载器主要有三种类型:Bootstrap或Primordial ClassLoader:该类加载器负责加载rt.jar
存在的内部核心Java类以及java.lang.*
包中存在的其他类。链接:此组件执行类或接口的链接。 由于此组件涉及新数据结构的分配,因此它可能会抛出OutOfMemoryError
并执行三个重要的活动:验证:这是检查类的二进制表示形式并验证生成的.class
文件是否有效的过程。初始化:此组件执行类加载的最后阶段,在该阶段中,所有静态变量都被分配了原始值,并且静态块从父类执行到子类。 由于JVM是多线程的,因此此过程需要仔细的同步,并且某些线程可能会尝试同时初始化同一类或接口。
图3:ClassLoader子系统概述
1.2.1 ClassLoader如何在Java中工作?
Java中的类加载器以三个原则工作,即委托,可见性和唯一性。
图4:Java中的类加载机制
代表团:据此: 每当虚拟机遇到类时,JVM都会检查是否加载了指定的.class
文件。可见性:据此: 应用程序类加载器可以看到父类加载器加载的类,但反之亦然,例如,如果类是由系统类加载器加载的,而稍后再次尝试使用扩展类加载器显式加载相同的类,则将抛出ClassNotFoundException
。运行。唯一性:据此: 由父类加载器加载的类不应该由子类加载器需要重新加载
1.2.2如何在Java中加载类?
类加载器是分层的。 应用程序中的第一个类是借助staticmain()
方法专门加载的。 所有后续类都可以通过静态或动态类加载技术来加载。
静态类加载:在这种技术中,类是通过new
运算符静态加载的动态类加载:在这种技术中,使用Class.forName()
或loadClass()
方法以编程方式加载类。 两者之间的区别在于,前者在加载对象后初始化该对象,而后者仅加载该类但不初始化该对象
1.3运行时数据区
如图5所示,该子系统分为五个主要部分,即
图5:JVM运行时数据区
方法区域:此组件保存每个.class
文件的类级别数据,例如元数据,常量运行时池,静态变量,方法的代码等。每个JVM只有一个方法区域,并且在所有类之间共享。 默认情况下,分配给该区域的内存是由JVM分配的,或者可以根据计算需要增加。 以下异常情况与此区域相关,即 如果方法区域不满足内存分配请求,那么JVM会抛出OutOfMemory
错误堆区域:此组件是JVM内存的一部分,所有对象及其对应的实例变量和数组都存储在JVM内存中。 该内存区域是在JVM启动时创建的,并且只有一个堆区域跨多个线程共享,因为存储在该区域中的数据不是线程安全的。 如果存储在堆内存中的对象没有引用,则垃圾回收器(即自动存储管理系统)回收该对象的内存; 此区域中的对象永远不会显式释放。 以下异常情况与此区域相关,即 如果计算需要的堆空间超过可用的堆空间,那么JVM会抛出OutOfMemory
错误堆栈区域:该组件还是JVM内存的一部分,所有临时变量都存储在该内存中。 该区域具有堆栈帧,并为每个线程分配一个帧。 一旦线程执行完成,该框架也会被破坏。 堆栈区域是线程安全的,因为它不是共享资源,并且分为三个子实体,例如: 局部变量数组:虚拟机使用这些局部变量在方法调用时传递参数
以下异常情况与此区域相关,即
如果线程处理要求虚拟机堆栈超出其允许的限制,则JVM会引发StackOverflow
错误PC(程序计数器)寄存器:该组件保存当前正在执行的JVM指令的地址。 Java中的每个线程都有其自己的PC寄存器来保存当前执行指令的地址本机方法堆栈:此组件用另一种语言编写,并保存本机方法信息。 Java中的每个线程都有一个单独的本机方法堆栈。 以下异常情况与此区域相关,即 如果线程处理需要本机堆栈超出其允许的限制,则JVM会引发StackOverflow
错误
这就是这篇文章的全部内容。 学习愉快!
2.结论
在本教程中,开发人员对虚拟机ClassLoader和Runtime Data Areas组件进行了概述。 您可以在“ 下载”部分中下载示例代码。
3.下载源代码
这是虚拟机ClassLoader和Runtime Data Areas组件的教程。
下载
您可以在此处下载本教程的源代码:JVM_Example
翻译自: //04/jvm-architecture-jvm-class-loader-and-runtime-data-areas.html