JVM 原理解释
JVM 全称是 Java Virtual Machine ,Java 虚拟机,这个 JVM 你是看不到的,它存在内存中。我们知道计算机的基本构成是:运算器、控制器、存储器、输入和输出设备,那这个 JVM 也是有这成套的元素,运算器是当然是交给硬件 CPU 还处理了,只是为了适应“一次编译,随处运行”的情况,需要做一个翻译动作,于是就用了JVM 自己的命令集,JVM 的命令集则是可以到处运行的,因为 JVM 做了翻译,根据不同的CPU ,翻译成不同的机器语言。
JVM 是一个内存中的虚拟机,那它的存储就是内存了,我们写的所有类、常量、变量、方法都在内存中。
JVM 的组成部分
Class Loader 类加载器
类加载器的作用是加载类文件(.class)到内存,Class Loader 加载的 class 文件是有格式要求的。
类加载的最终产品是位于运行时数据区的堆区的Class对象。
Class对象封装了类在方法区内部的数据结构。
并且向JAVA程序提供了访问类在方法区内的数据结构。
JVM加载class文件的原理机制
1. Java 中的所有类,必须被装载到 JMV 中才能运行,这个装载工作是由 JVM 中的类装载器完成的,类装载器所做的工作实质是把类文件从硬盘读取到内存中。
2. Java中的类大致分为三种:
a) 系统类
b) 扩展类
c) 由程序员自定义的类
3. 类装载方式,有两种:
a) 隐式装载,程序在运行过程中当碰到通过 new 等方式生成对象时,隐式调用类装载器加载对应的类到jvm中。
b) 显式装载,通过 class.forname() 等方法,显式加载需要的类。
4. 类加载的动态性体现
一个应用程序总是由n多个类组 成,Java 程序启动时,并不是一次把所有的类全部加载后再运行,它总是先把保证程序运行的基础类一次性加载到 JVM 中,其它类等到 JVM 用到的时候再加载,这样的好处是节省了内存的开销。因为java最早就是为嵌入式系统而设计的,内存宝贵,这是一种可以理解的机制,而用到时再加载这也是 Java 动态性的一种体现。
5.Java 类装载器
Java 中的类装载器实质上也是类,功能是把类载入 JVM 中,值得注意的是 JVM 的类装载器并不是一个,而是三个,层次结构如下:
Bootstrap Loader - 负责加载系统类
|
- - ExtClassLoader - 负责加载扩展类
|
- - AppClassLoader - 负责加载应用类
为什么要有三个类加载器,一方面是分工,各自负责各自的区块,另一方面为了实现委托模型。
6. 类加载器之间是如何协调工作的
前面说了,Java中有三个类加载器,问题就来了,碰到一个类需要加载时,它们之间是如何协调工作的,即 Java 是如何区分一个类该由哪个类加载器来完成呢。
在这里Java采用了委托模型机制,这个机制简单来讲,就是“类装载器有载入类的需求时,会先请示其Parent使用其搜索路径帮忙载入,如果 Parent 找不到,那么才由自己依照自己的搜索路径搜索类”,注意喔,这句话具有递归性。
JVM加载器机制
Java中,在调用类的静态成员,或新建该类的对象等之前,类一定要先装入Java虚拟机中,这是勿庸置疑的。但虚拟机怎样把类装载进来的呢?要经过三 步:装载(Load),链接(Link),初始化(Initializ)。其中链接又可分为校验(Verify),准备(Prepare),解析 (Resolve)三步。
一、装载(Load)
ClassLoader就是用来装载的。通过指定的className,找到二进制码,生成Class实例,放到JVM中。
ClassLoader从顶向下分为 Bootstrap ClassLoader、Extension ClassLoader、System ClassLoader以及User-Defined ClassLoader(分叉,可以多个)。如下图。
这是Tomcat装载器的例子:
装载过程从源码清析可见:
protected synchronized Class<?> loadClass(String name, boolean resolve)
{
// 先检查是否已被当前ClassLoader装载。
Class c = findLoadedClass(name);
if (c == null) {
try {
if (parent != null) {
// 如果没被当前装载,则递归的到父中装载。
c = parent.loadClass(name, false);
} else {
// 装载器树已到顶,还没找到的话就到Bootstrap装载器中找。注意:虽然Bootstrap是所有加载器的根,但它是C++实现的,不可能放到子的"parent"中,因此,第二层装载器是所有的根了。
c = findBootstrapClass0(name);
}
} catch (ClassNotFoundException e) {
// 如果祖先都无法装载,则用当前的装载。子类可在findClass方法中调用defineClass,把从自定义位置获得的字节码转换成Class。
c = findClass(name);
}
}
if (resolve) {
// Links the specified class.
resolveClass(c); // 注
}
return c;
}
注:
1. resolveClass(c)方法的注释是链接类,而不只是解析,从该即可看出。
调用resolveClass时语义上是去链接,是否真的链接了我不是很清楚,但可以肯定的是没有初始化。当A类中有static B b=new B()时,最晚会在初始化时去装载B。
如果改成static B b=null,那么把B.class删掉后,即使A已经链接,初始化过了,但也不会报错,也就是A所引用的B类没有被加载过。解析时难道没有真的去装入它所引用的B类?还是链接时,没有执行解析的步骤? 问题的关键就是 1.对“解析”的理解,解析时是否会去装载B类?2. JVM在链接时是否执行了解析?(毕竟有资料说,解析是可选步骤)
二、链接
链接就是把load进来的class合并到JVM的运行时状态中。
链接 是三个阶段中最复杂的一个。可以把它分成三个主要阶段:
- 校验。 对二进制字节码的格式进行校验,以确保格式正确、行为正确。
- 准备。 准备类中定义的字段、方法和实现接口所必需的数据结构。比如会为类中的静态变量赋默认值(int等:0, reference:null, char:'\u0000')。
-
解析。 装入类所引用的其他所有类。可以用许多方式引用类:
- 超类
- 接口
- 字段
- 方法签名
- 方法中使用的本地变量
Initialization of a class consists of executing its static initializers and the initializers for
static
fields (class variables) declared in the class. Initialization of an interface consists of executing the initializers for fields (constants) declared there.类的初始化包括:执行静态区块和静态方法的初始化。比如下面这两种代码都会被执行,包括new B()。
static{
...
}
static B b=new B();
接口中不允许有static initializer(也就是static{...}),所以对于接口,只会执行静态字段的初始化。
初始化前,装载,链接一定已经执行过!
类初始化前,它的直接父类一定要先初始化(递归),但它实现的接口不需要先被初始化。类似的,接口在初始化前,父接口不需要先初始化。
什么情况下,类的初始化会被触发?
A class or interface type T will be initialized immediately before the first occurrence of any one of the following:
- T is a class and an instance of T is created.
- T is a class and a static method declared by T is invoked.
- A static field declared by T is assigned.
- A static field declared by T is used and the field is not a constant variable (§4.12.4).
-
T is a top-level class, and an
assert
statement (§14.10) lexically nested within T is executed.
当使用类的字段时,即便可以通过子类或子接口访问该字段,但只有真正定义该字段的类会被触发初始化。如下例。
class Super { static int taxi = 1729; }
class Sub extends Super { static { System.out.print("Sub "); } }
class Test {
public static void main(String[] args) {
System.out.println(Sub.taxi);
}
}
只会输出“1729”,不会输出"Sub",也就是说,Sub其实没有被初始化。四、Class.forName()与ClassLoader.loadClass()
这两方法都可以通过一个给定的类名去定位和加载这个类名对应的 java.long.Class 类对象,区别如下:
1. 初始化
Class.forName()会对类初始化,而loadClass()只会装载或链接。可见的效果就是类中静态初始化段及字节码中对所有静态成员的初始工作的执行(这个过程在类的所有父类中递归地调用). 这点就与ClassLoader.loadClass()不同. ClassLoader.loadClass()加载的类对象是在第一次被调用时才进行初始化的。
你可以利用上述的差异. 比如,要加载一个静态初始化开销很大的类, 你就可以选择提前加载该类(以确保它在classpath下), 但不进行初始化, 直到第一次使用该类的域或方法时才进行初始化
2. 类加载器可能不同
Class.forName(String) 方法(只有一个参数), 使用调用者的类加载器来加载, 也就是用加载了调用forName方法的代码的那个类加载器。当然,它也有个重载的方法,可以指定加载器。 相应的, ClassLoader.loadClass()方法是一个实例方法(非静态方法), 调用时需要自己指定类加载器, 那么这个类加载器就可能是也可能不是加载调用代码的类加载器(调用代用代码类加载器通getClassLoader0()获得)
相关推荐
了解并熟练掌握JVM原理对于Java开发者至关重要,无论是编写高效代码还是排查性能问题,都有着深远的影响。通过阅读提供的"JVM原理.pdf",你可以更深入地理解这些概念,并结合实际应用,提升自己的编程技能。
"浅谈 JVM 原理" JVM(Java Virtual Machine)是一种虚拟机,它可以模拟完整的硬件系统功能,运行在一个完全隔离的环境中,提供了一个完整的计算机系统。JVM 可以分为三类:VMWare、Visual Box 和 JVM。其中,...
### JVM原理及调优 #### 一、JVM概述 JVM(Java Virtual Machine,Java虚拟机)是Java编程语言的基础,它作为一种软件层面的抽象计算机,能够在多种操作系统平台上执行Java字节码程序。Java编译器的目标是生成能够...
### JAVA JVM原理资料知识点 #### 一、语言处理器的基本结构 **语言处理器**是指能够处理某种编程语言的工具,常见的包括编译器、解释器、IDE等。 1. **编译器的基本结构**: - **词法分析器**:将源代码分割成...
JAVA应用JVM原理及参数调优深入讲解视频.1 JAVA应用JVM原理及参数调优深入讲解视频.2 JAVA应用JVM原理及参数调优深入讲解视频.3 JAVA应用JVM原理及参数调优深入讲解视频.4 JAVA应用JVM原理及参数调优深入讲解视频.5 ...
JVM 原理讲解和调优 JVM(Java Virtual Machine,Java 虚拟机)是 Java 语言的核心组件,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM 的主要功能是将 Java 字节码转换为...
通过以上对JVM原理和参数调优的深入学习,开发者可以更好地理解Java应用程序的运行机制,优化系统性能,解决可能出现的内存溢出、性能瓶颈等问题。本课程详细讲解了这些内容,无论你是初学者还是经验丰富的开发者,...
总的来说,JVM原理的深入理解可以帮助开发者更好地编写代码、优化性能和解决线上问题。冯立全通过分享,将JVM原理的理论与实践相结合,为听众提供了一个全面了解JVM的机会。这对于需要深入探讨Java生态系统和提高...
标题中提到了JVM原理、JVM调优、JVM内存模型和JAVA并发,这些都是Java虚拟机(JVM)相关的核心概念。JVM是运行Java字节码的虚拟计算机,为Java提供了一个跨平台的环境,确保Java程序可以在不同的操作系统上运行而...
理解JVM的工作原理对于提升Java应用的性能和稳定性具有重要意义。开发者可以通过对JVM进行调优,结合业务场景和应用需求,合理配置JVM内存大小、调整垃圾回收策略和类加载机制,从而达到优化应用性能的目的。
该文档是关于java虚拟机的原理,描述及调优视频,其中,详细讲述了jvm的运行机制,类装载器,GC算法,性能监控工具,堆,锁等内容。
Java虚拟机(JVM)是Java平台的核心组成...总结来说,JVM原理包括了它的整体结构、代码的编译执行流程、类加载的逻辑以及内存管理策略和垃圾回收机制。理解和掌握这些知识点对于深入理解Java程序的运行机制至关重要。
本文将深入探讨JVM的启动过程及其基本原理。 首先,我们需要理解JVM的基本概念。JVM是Java Virtual Machine的缩写,它是Java平台的核心组件之一。它的主要任务是将编译后的Java类文件(.class文件)中的字节码转换...
JVM原理-jvm内存及相关图示 JVM(Java Virtual Machine)是Java开发工具包(JDK)的一部分,它的主要作用是将Java字节码文件(.class文件)解释并执行,使得Java语言可以跨平台运行。JVM主要由类加载子系统、执行...
### Sun JVM原理与内存管理 #### 一、Sun JDK 1.6 GC (Garbage Collector) Sun JDK 1.6 的垃圾收集器(GC)是其内存管理的关键组成部分,它负责自动地回收不再使用的对象所占用的内存。本文将详细介绍Sun JDK 1.6 GC...
### JVM原理核心知识点详解 #### 一、Java虚拟机的生命周期 Java虚拟机的主要任务是在程序开始时启动,执行Java程序,并在程序结束时停止。一个运行中的Java虚拟机实例代表着一个正在执行的Java程序。 - **启动**...
### JVM原理、内存模型、性能调优 #### 一、JVM原理概述 Java虚拟机(JVM)是一种用于执行Java字节码的虚拟机。它为Java程序提供了一个独立于平台的运行环境,并且能够自动处理内存管理和垃圾回收等工作。JVM的核心...
JVM原理和调优是每个Java开发人员必须掌握的关键技能,这涉及到内存管理、垃圾收集、性能优化等多个方面。在深入理解JVM的工作机制后,我们可以更好地调整和优化应用程序,提升系统的性能和稳定性。 一、JVM结构与...
深入理解JVM原理和垃圾回收机制对于Java开发者来说至关重要,它能帮助你编写出更高效、更稳定的代码,避免内存泄漏和性能瓶颈。通过实践和学习,你可以掌握如何有效地配置和调优JVM,从而提升应用的整体性能。同时,...
### Java中JVM原理与实现 #### 一、引言 Java虚拟机(JVM)作为Java语言的基础支撑,是确保Java程序能够在不同平台上顺畅运行的关键技术。本文将深入探讨JVM的工作原理及其核心组成部分,包括类加载器、运行时数据区...