类文件格式
JVM使用一种硬件、操作系统无关的二进制格式来保存编译后的代码。
数据类型
和Java语言一样,JVM操作两种数据类型:基本类型和引用类型。
类型检验应该在编译期完成,JVM不需要负责类型检验。
JVM根据指令来分辨操作数的类型:
iadd -> int
ladd -> long
fadd -> float
dadd -> double
JVM显式的支持“对象”的概念。一个对象可以使一个动态分配的对象实例或一个数组。一个引用拥有引用类型。引用类型可以理解为指向对象或数组的指针。可以同时有多个引用指向一个对象实例或数组。对象实例和数组总是通过引用被操作,传递和测试(Tested via values of type reference)。
returnAddress类型
JVM中的returnAddress类型是 jsr,ret和jsr_w指令。returnAddress类型是指向JVM操作码的指针。returnAddress类型不是简单意义上的数值,不属于任何一种基本类型。Java程序无法动态地修改returnAddress。
boolean类型
JVM只boolean类型提供有限的支持。没有单独的JVM指令单独操作boolean值,Java源代码中对boolean类型变量的操作被编译为int类型的指令。JVM不直接的支持boolean类型的数组,而是使用操作byte数组的指令来操作boolean数组。比如baload,bastore。Java编译器将Java语言的true和false映射为JVM中的int类型的1和0。
引用类型
引用类型包括三中:class types, array types, interface types。他们的值指向动态创建的类对象,数组或实现接口的类对象。一个引用可以是空的(null)。空引用不指向任何对象。空引用不属于任何类型,但是可以被转换成任何类型。JVM Spec 不强制要求null在字节码中为某个值,如“0”。
运行时数据区域(Runtime Data Areas)
JVM定义了一组运行时数据区域。这些区域再JVM运行程序时使用。一些区域在JVM启动的时候就被创建,在JVM关闭时销毁。还有些区域是每个线程所有的。线程启动时创建,线程结束时销毁。
pc 寄存器
JVM支持多线程。每个线程都有自己的pc(program counter)寄存器。任意时刻JVM线程执行某个方法的代码。如果方法不是native的,那么pc指向当前执行的JVM指令。如果是native的,那么pc必须足够大来保存returnAddress或一个当前pingai平台下的本地指针。
JVM栈
每个线程都拥有一个私有的JVM stack,这个堆栈与线程一同创建。JVM栈和C语言的栈相似。由于JVM的Frame可以放在堆上,所以JVM stack可以是不连续的。JVM实现者应该让程序员可以控制初始栈的大小,并控制栈的最大最小值。JVM stack 可以动态增加。
Heap
JVM有一个堆,所有JVM中的线程共享这个堆。所有的类对象实例和数组都分配在堆上。
JVM堆在JVM启动的时候被创建。JVM提供一个垃圾收集者来管理堆。堆上的对象不需要程序员显式地销毁。堆可以是固定大小,也可以根据需要增加大小。堆可以是不连续的。
方法区域(Method Area)
JVM有一个方法区域,所有JVM中的线程共享这个区域。这个区域与C语言程序中的“text”段类似。在其中保存了每个类属的数据,比如 Runtime constant pool,field和method data,还有方法的字节码和构造函数,其中还包括类的“special methods”,还有实例和接口初始化代码。
Runtime constant pool
一个Runtime constant pool是代表了一个class文件中类或接口的常量表。其中包含若干常量,从编译期就固定的数值常量到编译期必须决定的方法和field的引用。Runtime constant pool类似与C语言中的符号表。
每个Runtime constant pool从JVM的Method Area 中分配。Runtime constant pool在类或接口被JVM创建的时候创建。
Native Method Stack
JVM可以使用传统的堆栈来支持本地方法。
Frame
Frame用来存储数据,部分返回结果,也用于动态连接,返回方法的结果,以及分发异常
每次调用方法,JVM都会再当前线程的Stack上创建一个Frame,当方法结束是销毁这个Frame。
每个Frame都有自己的局部变量数组,自己的操作数栈(operand stack)。
局部变量数组和操作数栈的大小在编译期就决定了。局部变量和操作数有当前Frame所属的方法提供。
Frame的大小由虚拟机的实现者决定。Frame所占用的内存可以在方法调用的时分配。
每个线程运行的某个时刻只能有一个Frame是活跃的,称为“当前Frame”。这个线程称为“当前线程”。包含这个方法的类称为“当前类”。当一个方法调用了另一个方法,那么它的Frame不在活跃,被调用的方法的Frame成为“当前Frame”。注意:两个线程创建的Frame是完全独立的。
局部变量
每个Frame都有一个局部变量数组,数组的长度取决于方法的局部变量个数。
单个局部变量可以存储:boolean, byte, char, short, int, float, reference和returenAddress
一对局部变量可以存储:long或double
局部变量用索引值来取址。第一个局部变量的索引是0。
JVM使用局部变量来传递方法参数。对于类方法,方法参数从局部变量“0”(零)开始。
对于实例方法,局部变量“0”被用来保存当前实例的引用值(this)。方法参数从局部变量“1”开始。
操作数栈(stack)
每个Frame都包含一个LIFO的栈,称为Operand Stack。该栈的最大深度在编译期决定,有创建Frame的方法代码决定。
JVM需要提供将局部变量或常量压入操作数栈的指令。其他指令可以操作栈上的数据,并将结果也压入栈。操作数栈也用于传递参数和接受返回值。
比如,iadd指令将两个int值加起来。这就需要被加的两个数在栈的最顶端。他们是由前面的指令压入栈的。两个数从栈中弹出。相加后的结果被压入栈。
动态连接(Dynamic Linking)
每个Frame包含一个指向当前 Runtime constant pool的引用,用来提供方法的动态链接。
方法代码是通过符号来引用变量和调用方法的。JVM动态的将符号翻译为具体的方法引用或变量的索引。
这就是Java实现晚绑定的机制。这种晚绑定使得代码变得更安全。
方法正常结束与异常结束
如果方法没有引起或抛出任何异常,那么方法会正常结束。需要指出的是,异常可以是由JVM直接抛出的,也可以是程序显式抛出的。
初始化方法
在JVM层次上,每个类的构造函数都有一个特殊的名字。这个名字由编译器提供。Java语言中不能直接使用这个名字。在JVM中,通过invokespecial指令来调用这个方法。
一个类或接口最多有一个类或接口初始化方法。这个方法是静态而且没有任何参数的。它有一个特殊的名字:。这个名字也有编译期提供,Java语言中不能直接用。类和接口的初始化方法有JVM隐式地调用。它们从不被某个JVM指令调用,而是作为类的初始化过程的一部分被调用。
异常
抛出异常会使当前方法异常结束。每个类的异常Handler被放在类文件的一个表中。
当异常发生的时候,JVM会从中找到合适的异常处理Handler来处理,如果当前方法没有合适的处理当前异常的Handler,则将当前方法的Frame弹出,扔掉Operand stack和局部变量。返回到当前方法的调用者中,再重复前面的过程,直到到达调用链条的顶端。如果最外层的方法也没有合适的Handler,就退出当前线程。
- 大小: 13.8 KB
分享到:
相关推荐
JVM结构:类加载器,执行引擎,本地方法接口,本地内存结构; 四大垃圾回收算法:复制算法、标记-清除算法、标记-整理算法、分代收集算法 七大垃圾回收器:Serial、Serial Old、ParNew、CMS、Parallel、Parallel Old...
在"【IT十八掌徐培成】Java基础第25天-06.JVM结构1"的课程中,我们将会深入探讨JVM的内部结构,了解它是如何使得Java具有跨平台特性的。 首先,JVM可以分为以下几个主要部分: 1. **类加载器(ClassLoader)**:它...
在本课程"【IT十八掌徐培成】Java基础第26天-03.JVM结构-finalize-gc"中,我们将深入探讨JVM的结构、`finalize`方法以及垃圾收集(Garbage Collection,简称GC)机制。以下是这些主题的详细阐述: 1. JVM结构: - ...
JVM结构+垃圾回收器+锁总结
### JVM基本原理及结构详解 #### 一、Java虚拟机(JVM)的逻辑与物理结构 JVM,即Java Virtual Machine,是运行Java字节码的虚拟机环境,它的设计目的是为了提供一个独立于硬件的运行环境,使得Java程序可以在任何...
1. **JVM结构与原理**:首先,我们需了解JVM的基本架构,包括类装载器、运行时数据区、执行引擎、本地方法接口和本地库。特别是堆内存、栈内存、方法区(元空间)以及垃圾收集机制,它们是理解JVM运行时行为的关键。...
### JVM结构与工作原理 JVM主要由以下几个部分组成: 1. **类加载器(ClassLoader)**:负责加载.class文件,将字节码转换为内存中的类。 2. **运行时数据区(Runtime Data Area)**:包括方法区、堆、栈、本地方法...
在这个资源中,我们将详细讨论 JVM 内存参数的配置和调优,包括 JVM 的结构、内存管理、垃圾回收、堆和非堆内存、内存分配和限制等方面。 JVM 结构 JVM 的结构主要由六个部分组成:JVM API、JVM 内部组件、平台...
**一、JVM结构** JVM主要由以下几个部分组成: 1. **类装载器**:负责加载.class文件,将其转换成Java对象,并存放在内存中。 2. **运行时数据区**:包括堆、方法区、虚拟机栈、本地方法栈和程序计数器。堆存储...
### JVM内存结构详解 #### 一、概述 Java虚拟机(JVM)作为Java程序的运行环境,其核心组件之一便是内存管理系统。理解JVM的内存布局对于开发高性能的应用程序至关重要。本文将详细介绍JVM内存结构及其各个组成部分...
Java虚拟机(JVM)内存结构与配置是Java开发者必须理解的重要概念,它涉及到程序的运行效率和稳定性。本文将详细解析JVM的内存结构、内存分配策略以及相关的配置参数。 1. **JVM内存结构** JVM内存主要分为以下几...
理解JVM结构对于优化性能至关重要。例如,在多web应用共用一个服务器(如Tomcat)的情况下,每个应用有自己的类加载器,从而在逻辑上隔离各个应用,减少干扰。 接下来,我们探讨堆与栈的区别: - **栈** 主要处理...
1. **JVM结构** JVM由类加载器、运行数据区、执行引擎、本地方法接口和本地库组成。类加载器负责加载字节码文件,运行数据区包括堆、栈、方法区等,执行引擎负责解释或编译执行字节码,本地方法接口用于调用非Java...
1. **JVM结构与工作原理**: - 类加载机制:了解类如何被加载、验证、准备、解析和初始化,以及双亲委托模型。 - 运行时数据区:包括堆、方法区、虚拟机栈、本地方法栈和程序计数器等各个区域的作用和管理策略。 ...
1. **JVM结构** JVM主要由以下几个部分组成: - **类装载器(Class Loader)**:负责加载字节码文件(.class)到JVM内存。 - **运行时数据区(Runtime Data Areas)**:包括方法区、堆、虚拟机栈、本地方法栈和...
**一、JVM结构与工作流程** 1. **类加载子系统**: JVM负责加载、验证、准备、解析和初始化类。类加载器包括启动类加载器、扩展类加载器和应用类加载器等,它们遵循双亲委派模型。 2. **运行时数据区**: 包括方法区...
一、JVM结构 JVM主要由以下几个核心组件构成: 1. **类加载器(Class Loader)**:负责加载类文件,将.class文件转换为内存中的类对象。 2. **运行时数据区(Runtime Data Area)**:包括堆(Heap)、方法区...
1. **JVM结构与工作原理**: - 类加载机制:JVM如何加载类文件,包括加载、验证、准备、解析和初始化五个阶段。 - 运行时数据区:堆、栈、方法区、本地方法栈、程序计数器等区域的定义和作用。 - 字节码执行引擎...
《JVM高级特性与最佳实践》是一本专注于Java虚拟机(JVM)学习的书籍,适合广大Java开发人员。...通过此书,读者不仅可以获得关于JVM结构和工作原理的全面认识,还能掌握在开发过程中应用这些知识的技巧和方法。
一、JVM结构 JVM主要由以下几个部分组成: 1. **类装载器(ClassLoader)**:负责加载.class文件,解析字节码并将其转换为运行时数据结构。 2. **运行时数据区(Run-Time Data Areas)**:包括方法区、堆、虚拟机栈、...