竹笋

首页 » 问答 » 问答 » JVM框架综述
TUhjnbcbe - 2023/1/13 21:19:00
彭洋出诊时间 http://m.360xh.com/xinwen/3259/65468.html

从JVM的总体上看,它解决了3个问题:

Java程序的内存管理(GC运行时数据区)。

JavaClass二进制字节流的加载(ClassLoader)。

Java程序的执行(执行引擎)。

如下图所示:

虚拟机基本架构

在我们的日常开发中,最和我们息息相关的就是1和2了,比如GC调优,内存故障排查,再比如使用自定义的类加载器去实现一些特定的逻辑,就如我们之前分析的tomcat源码中的类加载器用于隔离不同版本的相同类库,必须要使用自定义的类加载器。

1.Java程序的内存管理(GC运行时数据区)

1.1.运行时数据区

从上图中可以看出,虚拟机内存管理主要由几个部分组成:

Java堆(存放对象的地方)

Java栈(在HotSpot实现中,本地方法栈和虚拟机栈合二为一)

PC寄存器(也称为程序计数器)

方法区(JDK8中已经将方法区去除,改为元数据区,解决了方法区----也称为永久代的内存溢出)。

直接内存(大小不限制于Java堆,直接向操作系统申请,使用场景于读写频繁的场合,例如NIO)

1.2.垃圾回收系统

Java程序员之所以不需要显式的释放内存,一切都归功于GC,GC解放了Java程序员的双手。GC系统会在后台清除无用的实例对象,释放内存空间。

而JVM中的GC可谓是一个庞大的系统,其中分为几个部分:

判断什么是垃圾对象

垃圾回收算法

各种各样的垃圾收集器

我们将会在后面慢慢讲解。

2.JavaClass二进制字节流的加载(ClassLoader)

2.1类加载器

对于Java虚拟机来说,Class文件是一个重要的接口,无论使用何种语言进行软件开发,只要能将源文件编译为正确的Class文件,那么这种语言就可以在Java虚拟机上运行。可以说,Class文件就是虚拟机的基石。

如图所示:

各种语言都可以在JVM上运行

从上图可以看出,虚拟机不拘泥于Java语言,任何一个源文件只要能编译成Class文件的格式,就可以在JVM上运行!Class文件格式就像是一个接口,只要遵守这个接口,就能够在JVM上运行。

2.2类加载器的工作流程

Class文件通常是以文件的方式存在(任何二进制流都可以是Class类型),但只有能被JVM加载后才能被使用,才能运行编译后的代码。系统装在Class类型可以分为加载,链接和初始化三个步骤。其中,链接也可分为验证,准备和解析3步骤。如图所示:

Class文件转载过程

2.3类装载的条件

JVM不会无故装载Class文件,只有在必要的时候才装载,哪几个时候呢?

当创建一个类的实例是,比如使用new关键字,或者通过反射,克隆,反序列化。

当调用类的静态方法时,即当使用字节码invokstatic指令。

当使用类或接口的静态字段时(final常量除外),比如,使用getstatic或者pustatic指令。

当时用Java.lang.reflect包中的方法反射类的方法时。

当初始化子类,要求先初始化父类。

作为启动虚拟机,含有main()方法的那个类。

以上6种情况属于主动调用,主动调用会触发初始化,还有一种情况是被动调用,则不会引起初始化。

2.4类加载器的双亲委派模型

先来看一个著名的图:

类加载器双亲委派模型

虚拟机为了保护应用程序内出现多个类名相同的类对象,因此发明了这个机制:当JVM需要使用一个类时,在判断类是否已经被加载时,会先从当前底层类加载器进行判断。当系统需要加载一个类时,会从顶层类开始加载,依次向下尝试,直到成功,否则抛出ClassNotFound异常。

#总结

这篇文章主要是为了后面的详细文章做一个大纲,因此只是讲述以JVM的一些基本的框架和概念,后面讲详细的讲述内部细节。让我们学习虚拟机更加的有条理。

1
查看完整版本: JVM框架综述