JVM-JVM体系结构与工作方式

282 阅读4分钟

一、JVM体系结构

  1. 什么是JVM
    JVM的全称是Java Virtual Machine(Java虚拟机),它通过模拟一个计算机来达到一个计算机所有的功能,它实现了Java的跨平台的能力。
    JVM是:
  • 一个抽象规范,这个规范约束了JVM到底是什么,它由哪些组成部分。
  • 一个具体的实现,所谓具体的实现就是不同的厂商按照这个抽象的规范用软件或者软件和硬件结合的方式在相同或者不同的的平台上的具体实现。
  • 一个运行中的实例,当其运行一个Java程序时,他就是一个运行中的实例,每个运行中的Java程序都是一个JVM实例。

  JVM也和实体机一样必须有一套适合的指令集,这个指令集能被JVM解析执行。这个指令集我们称之为JVM字节码指令集,符合class文件规范的字节码都可以被JVM执行。

  1. JVM体系结构
    除了指令集以外,JVM的结构基本上由四部分组成:
  • 类加载器,在JVM启动时或者在类运行时将需要的class文件加载进JVM中。
  • 执行引擎,执行引擎的任务是负责执行class文件中包含的字节码指令,相当于时机机器上的CPU。
  • 内存区,将内存划分为若干个区域以模拟实际机器上的存储、记录和调动模块,如实际机器上的各种功能的寄存器或者PC指针的记录器等。
  • 本地方法调用,调用C或者C++实现的本地方法的代码返回结果。

二、JVM工作方式

前面简单介绍了JVM的基本结构,下面简单分析一下执行引擎是如何工作的。

通常一个程序从编写到执行会经历以下一些阶段:
源代码-->预处理器-->编译器-->汇编程序-->目标代码-->链接器-->可执行程序

  1. 机器如何执行代码
    除了源代码和最后的可执行程序,中间所有的环节都是由现代意义上的编译器统一完成的。
    值得注意的是,我们通常所说的编译器都是将某种高级语言直接编译成可执行的目标机器语言(实际上在某种操作系统中是需要动态链接的目标二进制文件:在Windows下是dynamic link library,DLL;在Linux下是Shared Library,SO库)。但实际上还有一些编译器是将一种高级语言翻译为另一种高级语言,如Java编译器。

  2. 基于栈架构的JVM
    JVM执行字节码的指令是基于栈的架构,也就是所有的操作数必须先入栈,然后根据指令中的操作码选择从栈顶弹出若干个元素进行计算后在将结果压入栈中。在JVM中操作数可以存放在每一个栈帧中的一个本地变量集中,即在每一个方法调用时就会给这个方法分配一个本地变量集,这个本地变量集在编译时就已经确定,所以操作数入栈可以直接是常量入栈或者从本地变量集中取一个变量压入栈中。这和一般基于寄存器的操作不同,一个操作需要频繁地入栈和出栈,如进行一个加法操作,如果两个操作数都在本地变量中,那么一个加法操作需要5次栈操作,分别是将两个操作数从本地变量入栈(2次入栈操作),再讲两个操作数出栈用于加法运算(2次操作),在将结果压入栈中(1次操作)。

使用栈架构的原因(不使用寄存器架构;这里的架构是指在一个指令中的操作数是如何存取的):

  • JVM设计为与平台无关,因部分机器芯片上的寄存器没有规律或者过少。
  • 为了指令的紧凑性。
  1. 执行引擎的架构
    每当创建一个新的线程时,JVM会为这个线程创建一个Java栈(虚拟机栈),同时会为这个线程分配一个PC寄存器(程序计数器),并且这个PC寄存器会指向这个线程的第一行可执行代码。每当调用一个新的方法时会在这个栈上创建一个新的栈帧数据结构,这个栈帧会保留这个方法的元信息,如在这个方法中定义的局部变量、一些用来支持常量池的解析、正常的方法返回及异常处理机制等。
    JVM在调用某些指令时可能需要使用到常量池中的一些常量,或者获取常量代表的数据或者这个数据指向的实例化的对象,而这些信息都存储在所有线程共享的方法区和Java堆中。