Java虚拟机内部体系结构(摘记,待完善):)

简介:

Java虚拟机体内部系结构包括class文件、类装载子系统、运行时数据区、之行引擎、本地方法调用结构,其中运行时数据区包括方法区、堆、Java栈、程序计数器、本地方法栈等。具体结构如下图所示(摘自Inside Java Virtual Machine):


 

1.       class文件

Java中,所有源文件都编译成二进制的字节码,然后由虚拟机装载运行。一般这样的字节码是以class文件的形式存在。在运行时,由ClassLoader类(System ClassLoader or User-defined ClassLoader)找到对应的class文件,读取其中的字节码,然后交由虚拟机解析运行。

class文件中,包含了定义一个类或接口的所有信息,包括类名、访问权限、父类名、继承的所有接口、所有字段、所有方法、方法中的代码、属性等信息,并且每个class文件的开头还包含了魔术值和版本信息,魔术值用以标识当前的字节码是合法的字节码,版本表示生成当前字节码的编译器版本,从而虚拟机获知其版本而做特定处理,如果对于虚拟机不支持的字节码版本号拒绝加载。

class文件中,很多信息都是以字符串的形式存放,比如对外部类成员或方法的引用,这些字符串信息在链接的时候由虚拟机解析。每个Java类,不管是包成员类还是内部类都会生成一个单独的class文件,因而class文件是相对独立的。详细信息参考class文件格式。

 

2.       类装载子系统

类装载子系统负责查找class文件,读取字节码,做部分简单的检验,如魔数是否正确,版本是否受支持,各种数据格式是否正确等。部分解析后的字节码数据存放到方法区中,最后创建字节码代表的类或接口的Class实例。

Java中,类装载系统是通过ClassLoader来完成的。虚拟机规范中,定义了启动类装载器和用于定义类装载器。在sun提供的虚拟机中,包括了启动类装载器、扩展类装载器、系统类装载器、用户定义类装载器。他们以父子链的方式组织在一起。除了启动类装载器,其他的装载器都是ClassLoader的子类。ClassLoader定义了一些方法可以帮助用户定义自己的类装载器,如defineClass等。详情参考Java中的ClassLoader

 

如何卸载类数据?(第七章)

 

3.       运行时数据区

运行时数据区保存了所有在运行时的信息。包括方法区、Java栈、堆、程序寄存器、本地方法栈等。其中方法区和堆只在虚拟机中保存一份实例,因而需要处理多线程的同步问题;Java栈、程序寄存器是每个线程中有单独的实例,因而对不同的线程,他们的数据是私有的。

 

3.1   方法区

方法区中保存了读取的字节码信息(包括常量池,静态方法和静态成员信息)、字节码代表的Class类实例、一个指向加载它的ClassLoader实例。

Java程序可以有两种方式来获取某个类的Class实例:

1.       Class.forName()方法

2.       Object.getClass()方法

通过Class实例获取和该类或接口相关的任何信息。参考Class类的定义。

(注:对有启动ClassLoader加载的类,Class方法中的getClassLoader方法返回null

 

为加快执行速度,可以在方法区中引入方法表机制,记录能被外界调用的该类的实例方法,包括父类中继承下来的方法。(第八章详细介绍?)

 

方法区中根据类名搜索类信息,算法:散列、搜索树等。

 

3.2   Java

虚拟机为每个线程生成一个Java栈,因而对不同的线程,栈内的数据都是私有的。Java栈由栈帧组成,Java栈的操作只有两种,压入栈帧和弹出栈帧。线程中每个方法的调用都会在Java栈压入一个栈帧;每次方法返回(正常方法或抛异常返回),该方法对应的栈帧都会从栈中弹出。

 

3.2.1          栈帧

栈帧由操作数栈、局部变量区和栈帧数据组成。由于Java中的指令是基于栈而设计的,因而很多指令的默认操作数就是操作数栈中的数据。操作数栈用于保存指令的操作数和指令操作后的结果。

局部变量区用于保存当前方法的局部变量。

栈帧数据区则保存当前栈帧的信息,如指向当前类常量池的指针,用于操作数为常量池索引的指令;还有一些和特定虚拟机实现相关的信息和调试信息。

 

3.3   程序寄存器

每个线程在执行时都会保存当前指令的下一条指令的地址,以控制程序的之行流程。

 

3.4   

堆保存了程序在运行时的所有对象。在Java中,所有的对象都是保存在堆中的,而外部通过对象的引用来访问对象。由于Java存在垃圾回收器,因而Java对象可能被移动,以减少内存碎片。其中一种实现可以很好的解决移动对象而需要改变所有该对象的引用变量的技术,即将堆分为句柄池和对象池。对象池中的对象保存了对象的真正内容,而句柄池中的项包含两个指针,一个指向对象,一个指向类数据。一个对象引用就是指向句柄的之战。这样当需要移动对象时,只要改变句柄池中指向对象的指针值即可。然而这种设计是以牺牲速度为代价的,因为这样每次访问对象就要多经历一次指针定位。

 

在某些垃圾回收器实现中,对象需要额外的信息,如果引用计数的垃圾收集器,需要为每个对象记录引用计数信息;而对另外有些机制,则可能需要暂时保存某些数据。这些额外的数据可以保存在类中,也可以在记录在其他地方。类似的还有同步机制中的数据和记录是否已经调用过finalize方法的信息。

 

Java中有指令用于在内存中分配对象,却没有显式的指令来释放内存中的对象。

 

3.5   本地方法栈

Java方法调用本地方法的时候,当前线程的程序寄存器是不确定的值。程序的执行也转向本地方法。本地方法可以正常返回,也可以抛出异常。抛出的异常会在调用该本地方法的指令中重新抛出。

 

4.       执行引擎

每个用户线程(即不包括垃圾回收线程等)都有一个执行引擎实例,用以执行字节码指令。

 

5.       本地方法接口

Java程序可以通过本地方法接口来调用本地方法。

相关文章
|
22天前
|
存储 监控 算法
深入探索Java虚拟机(JVM)的内存管理机制
本文旨在为读者提供对Java虚拟机(JVM)内存管理机制的深入理解。通过详细解析JVM的内存结构、垃圾回收算法以及性能优化策略,本文不仅揭示了Java程序高效运行背后的原理,还为开发者提供了优化应用程序性能的实用技巧。不同于常规摘要仅概述文章大意,本文摘要将简要介绍JVM内存管理的关键点,为读者提供一个清晰的学习路线图。
|
1月前
|
Java Shell Windows
java Runtime.exec()执行shell/cmd命令:常见的几种陷阱与一种完善实现
java Runtime.exec()执行shell/cmd命令:常见的几种陷阱与一种完善实现
46 1
|
2月前
|
存储 算法 Java
Java虚拟机(JVM)的内存管理与性能优化
本文深入探讨了Java虚拟机(JVM)的内存管理机制,包括堆、栈、方法区等关键区域的功能与作用。通过分析垃圾回收算法和调优策略,旨在帮助开发者理解如何有效提升Java应用的性能。文章采用通俗易懂的语言,结合具体实例,使读者能够轻松掌握复杂的内存管理概念,并应用于实际开发中。
|
3月前
|
Java Shell Windows
java Runtime.exec()执行shell/cmd命令:常见的几种陷阱与一种完善实现
java Runtime.exec()执行shell/cmd命令:常见的几种陷阱与一种完善实现
156 5
|
3月前
|
存储 算法 Java
深入解析 Java 虚拟机:内存区域、类加载与垃圾回收机制
本文介绍了 JVM 的内存区域划分、类加载过程及垃圾回收机制。内存区域包括程序计数器、堆、栈和元数据区,每个区域存储不同类型的数据。类加载过程涉及加载、验证、准备、解析和初始化五个步骤。垃圾回收机制主要在堆内存进行,通过可达性分析识别垃圾对象,并采用标记-清除、复制和标记-整理等算法进行回收。此外,还介绍了 CMS 和 G1 等垃圾回收器的特点。
133 0
深入解析 Java 虚拟机:内存区域、类加载与垃圾回收机制
|
4月前
|
Java
Java常见JVM虚拟机指令(47个)
Java常见JVM虚拟机指令(47个)
80 3
Java常见JVM虚拟机指令(47个)
|
5月前
|
监控 Oracle Java
(一)JVM成神路之初识虚拟机 - 探寻Java虚拟机的前世今生之秘
JVM(Java Virtual Machine)Java虚拟机的概念大家都不陌生,Java之所以可以做到“一次编译,到处运行”的跨平台性,其根本原因就在于JVM。JVM是建立在操作系统(OS)之上的,Java虚拟机屏蔽了开发人员与操作系统的直接接触,我们在通过Java编写程序时,只需要负责编写Java代码即可,关于具体的执行则会由JVM加载字节码后翻译成机械指令交给OS执行。
101 1
|
4月前
|
Java 数据安全/隐私保护 Windows
【Azure Developer】使用Java代码启动Azure VM(虚拟机)
【Azure Developer】使用Java代码启动Azure VM(虚拟机)
|
4月前
|
存储 Java API
【Azure Developer】通过Azure提供的Azue Java JDK 查询虚拟机的CPU使用率和内存使用率
【Azure Developer】通过Azure提供的Azue Java JDK 查询虚拟机的CPU使用率和内存使用率
|
1月前
|
缓存 Prometheus 监控
Elasticsearch集群JVM调优设置合适的堆内存大小
Elasticsearch集群JVM调优设置合适的堆内存大小
291 1