admin管理员组

文章数量:1032824

什么是 Java 中的 JVM

Java 中的 Java 虚拟机程序整个执行过程的核心。

它基本上是一个程序,提供Java程序执行所需的运行时环境。

换句话说,Java虚拟机(JVM)是一种抽象的计算机机器,负责在特定硬件平台上执行Java字节码(一组高度优化的指令)。它也被称为Java运行时系统。

JVM的规范由Sun Microsystem提供,其实现提供了一个运行时环境来执行我们的Java应用程序。JVM实现被称为Java运行时环境(JRE)。

由于 JVM 不依赖于平台,因此,它可用于许多硬件和软件平台。

Java 虚拟机的内部体系结构 (JVM)


让我们了解一下JVM的内部架构,如下图所示。

如上图所示,JVM包含以下主要组件:

  1. 类加载器子系统
  2. 运行时数据区域
  3. 执行引擎
  4. 本地方法接口
  5. Java 原生库

运行时数据区域由以下子组件组成,如下所示:

  1. 方法区
  2. Java堆
  3. Java 栈
  4. PC寄存器
  5. 本地方法栈

JVM在内部如何工作?


Java 虚拟机执行以下操作以执行程序。它们如下:

a) 将代码加载到内存中。

b) 验证代码。

c) 执行代码

d) 提供运行时环境。

当我们用 Java 制作程序时,.java程序代码被 Java 编译器转换为由字节码指令组成的.class文件。这个 Java 编译器在 JVM 之外。Java 虚拟机一般会执行以下操作,如下所示:

  1. 此.class文件被传输到JVM的类加载器子系统,如上图所示。

在 JVM 中,类装入器子系统是执行以下功能的模块或程序:

a) 首先,类加载器子系统将.class文件加载到内存中。

b) 然后字节码验证器验证所有字节码指令是否正确。如果发现任何指令可疑,则立即拒绝进一步的执行过程。

c) 如果字节码指令正确,它会分配必要的内存来执行程序。

在JVM中内存分为 5 个独立的部分,称为运行时数据区域。它包含程序执行期间的数据和结果。这些区域如下:

  1. 方法区域:

方法区域是一个内存块,用于存储 Java 程序的类代码、变量代码和方法。这里的方法是指在类中声明的函数。

  1. Java堆:

这是创建对象的运行时数据区域。当 JVM 加载一个类时,会立即在其中构建一个方法和一个堆区域。

  1. Java栈:

方法代码存储在“方法”区域中。但是在方法执行期间,它需要更多的内存来存储数据和结果。此内存在 Java 栈上分配。

Java 栈是执行 Java 方法的内存区域。在 Java 栈中,将创建一个单独的帧来执行该方法。

每次调用方法时,都会在栈中创建一个新帧。方法调用完成后,将销毁与其关联的帧。

JVM总是创建一个单独的线程(或进程)来执行每个方法。

  1. PC寄存器:

PC(程序计数器)寄存器是那些包含当前正在执行的JVM指令的存储器地址的寄存器(内存区域)。

  1. 本地方法栈:

Java程序的方法在Java栈上执行。同样,程序或应用程序中使用的本机方法在本地方法栈上执行。

通常,要执行本机方法,需要 Java 本机方法库。这些头文件通过称为本机方法接口的程序定位并连接到 JVM。

执行引擎


执行引擎由两部分组成:解释器和 JIT(实时)编译器。它们将字节码指令转换为机器码,以便处理器可以执行它们。

在Java中,JVM实现同时使用解释器和JIT编译器将字节码转换为机器码。这种技术称为自适应优化器。

通常,任何编程语言(如C / C++,Fortran,COBOL等)都将使用解释器或编译器将源代码流转换为机器代码。

现在,两个主要问题是:为什么两者都需要解释器和JIT编译器,以及两者如何同时工作?

在理解这一点之前,我们将知道什么是 Java 语言中的 JIT 编译器?

什么是Java中的JIT编译器?


Java 中的 JIT 编译器是 JVM 的一部分,用于提高 Java 程序的执行速度。

换句话说,它用于提高程序执行的性能。它有助于减少执行程序所需的时间。

解释器和 JIT 编译器如何在 Java 中同时工作?


为了理解这一点,让我们考虑下面示例代码。假设这些是字节码指令:

代码语言:javascript代码运行次数:0运行复制
print x;
print y;
Repeat the following execution 10 times by changing the values of i from 1 to 10:
print z;

假设在没有Jit编译器帮助下,以下假设场景执行过程如下:

首先Java 解释器从第一条指令开始执行过程。它解释打印 x;转换为机器代码并将其传输到微处理器。

为此,假设 Java 解释器花了 2 纳秒的时间来完成它。微处理器获取它,执行它,并在屏幕上显示 a 的值。

接着,解释器回到内存中,阅读第二条指令打印 y;并需要另外 2 纳秒将其转换为机器代码。然后将机器代码提供给处理器,处理器执行它。

同样,解释器回来读取第 3 条指令,这是一个循环语句 print z;它应该做 10 次。


假设,解释器第一次需要 2 纳秒才能将 print z 转换为机器代码。

将此机器代码提供给处理器后,它返回内存,读取打印 z;第 2 次指令,再需要 2 纳秒才能将此指令转换为机器代码。然后解释器将此机器代码提供给处理器执行。

同样,解释器回来并读取打印 z;并第三次转换它,再花 2 纳秒。像这样,Java 解释器将转换打印 z;指令进入机器代码10次。

因此,解释器总共需要 10 x 2 = 20 纳秒才能完成此循环。此过程既费时又效率低。

这就是 JVM 不将此字节码指令分配给解释器的原因。它将此代码分配给 JIT 编译器。

在这里,术语编译器是指将Java虚拟机的指令集转换为特定处理器的指令集的转换器。

JIT 编译器如何执行循环指令?


让我们了解 Java 中的 JIT 编译器如何执行循环指令。

首先,JIT 编译器读取 print z 指令,然后将其转换为机器代码。为此,假设 JIT 编译器需要 2 纳秒才能完成此任务。

现在,JIT 编译器分配一个内存块,并将此机器代码指令推送到该内存中。为此,假设还需要 2 纳秒才能完成它。因此,JIT 编译器总共花费了 4 纳秒。

接下来,处理器将从内存中获取此机器代码指令并执行 10 次。

现在您可以观察到 JIT 编译器仅花费 4 纳秒即可完成执行,而解释器需要 20 纳秒才能执行相同的循环。

因此,JIT 编译器提高了执行过程的速度。


这里再次出现一个问题,为什么前两条指令不被JVM分配给JIT编译器。

原因很清楚。JIT 编译器转换每条指令需要 4 纳秒,而解释器实际上只需要 2 纳秒来转换每条指令。

当.class文件加载到内存中时,JVM首先尝试确定哪些代码要提供给解释器,哪些代码要提供给JIT编译器,以便性能更好。

提供给 JIT 编译器的代码块在 Java 中也称为热点。Java语言中的这个特性确实提高了程序在运行时的执行时间,特别是当它要多次执行时。

尽管不建议这样做,但也可以关闭 JIT 编译器选项。

因此,Java 解释器和 JIT 编译器同时工作,将字节码指令转换为机器码指令。

JVM中的垃圾回收器有助于清理未使用的内存,以提高程序的效率。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2008-08-21,如有侵权请联系 cloudcommunity@tencent 删除教程内存javajvm编译器

什么是 Java 中的 JVM

Java 中的 Java 虚拟机程序整个执行过程的核心。

它基本上是一个程序,提供Java程序执行所需的运行时环境。

换句话说,Java虚拟机(JVM)是一种抽象的计算机机器,负责在特定硬件平台上执行Java字节码(一组高度优化的指令)。它也被称为Java运行时系统。

JVM的规范由Sun Microsystem提供,其实现提供了一个运行时环境来执行我们的Java应用程序。JVM实现被称为Java运行时环境(JRE)。

由于 JVM 不依赖于平台,因此,它可用于许多硬件和软件平台。

Java 虚拟机的内部体系结构 (JVM)


让我们了解一下JVM的内部架构,如下图所示。

如上图所示,JVM包含以下主要组件:

  1. 类加载器子系统
  2. 运行时数据区域
  3. 执行引擎
  4. 本地方法接口
  5. Java 原生库

运行时数据区域由以下子组件组成,如下所示:

  1. 方法区
  2. Java堆
  3. Java 栈
  4. PC寄存器
  5. 本地方法栈

JVM在内部如何工作?


Java 虚拟机执行以下操作以执行程序。它们如下:

a) 将代码加载到内存中。

b) 验证代码。

c) 执行代码

d) 提供运行时环境。

当我们用 Java 制作程序时,.java程序代码被 Java 编译器转换为由字节码指令组成的.class文件。这个 Java 编译器在 JVM 之外。Java 虚拟机一般会执行以下操作,如下所示:

  1. 此.class文件被传输到JVM的类加载器子系统,如上图所示。

在 JVM 中,类装入器子系统是执行以下功能的模块或程序:

a) 首先,类加载器子系统将.class文件加载到内存中。

b) 然后字节码验证器验证所有字节码指令是否正确。如果发现任何指令可疑,则立即拒绝进一步的执行过程。

c) 如果字节码指令正确,它会分配必要的内存来执行程序。

在JVM中内存分为 5 个独立的部分,称为运行时数据区域。它包含程序执行期间的数据和结果。这些区域如下:

  1. 方法区域:

方法区域是一个内存块,用于存储 Java 程序的类代码、变量代码和方法。这里的方法是指在类中声明的函数。

  1. Java堆:

这是创建对象的运行时数据区域。当 JVM 加载一个类时,会立即在其中构建一个方法和一个堆区域。

  1. Java栈:

方法代码存储在“方法”区域中。但是在方法执行期间,它需要更多的内存来存储数据和结果。此内存在 Java 栈上分配。

Java 栈是执行 Java 方法的内存区域。在 Java 栈中,将创建一个单独的帧来执行该方法。

每次调用方法时,都会在栈中创建一个新帧。方法调用完成后,将销毁与其关联的帧。

JVM总是创建一个单独的线程(或进程)来执行每个方法。

  1. PC寄存器:

PC(程序计数器)寄存器是那些包含当前正在执行的JVM指令的存储器地址的寄存器(内存区域)。

  1. 本地方法栈:

Java程序的方法在Java栈上执行。同样,程序或应用程序中使用的本机方法在本地方法栈上执行。

通常,要执行本机方法,需要 Java 本机方法库。这些头文件通过称为本机方法接口的程序定位并连接到 JVM。

执行引擎


执行引擎由两部分组成:解释器和 JIT(实时)编译器。它们将字节码指令转换为机器码,以便处理器可以执行它们。

在Java中,JVM实现同时使用解释器和JIT编译器将字节码转换为机器码。这种技术称为自适应优化器。

通常,任何编程语言(如C / C++,Fortran,COBOL等)都将使用解释器或编译器将源代码流转换为机器代码。

现在,两个主要问题是:为什么两者都需要解释器和JIT编译器,以及两者如何同时工作?

在理解这一点之前,我们将知道什么是 Java 语言中的 JIT 编译器?

什么是Java中的JIT编译器?


Java 中的 JIT 编译器是 JVM 的一部分,用于提高 Java 程序的执行速度。

换句话说,它用于提高程序执行的性能。它有助于减少执行程序所需的时间。

解释器和 JIT 编译器如何在 Java 中同时工作?


为了理解这一点,让我们考虑下面示例代码。假设这些是字节码指令:

代码语言:javascript代码运行次数:0运行复制
print x;
print y;
Repeat the following execution 10 times by changing the values of i from 1 to 10:
print z;

假设在没有Jit编译器帮助下,以下假设场景执行过程如下:

首先Java 解释器从第一条指令开始执行过程。它解释打印 x;转换为机器代码并将其传输到微处理器。

为此,假设 Java 解释器花了 2 纳秒的时间来完成它。微处理器获取它,执行它,并在屏幕上显示 a 的值。

接着,解释器回到内存中,阅读第二条指令打印 y;并需要另外 2 纳秒将其转换为机器代码。然后将机器代码提供给处理器,处理器执行它。

同样,解释器回来读取第 3 条指令,这是一个循环语句 print z;它应该做 10 次。


假设,解释器第一次需要 2 纳秒才能将 print z 转换为机器代码。

将此机器代码提供给处理器后,它返回内存,读取打印 z;第 2 次指令,再需要 2 纳秒才能将此指令转换为机器代码。然后解释器将此机器代码提供给处理器执行。

同样,解释器回来并读取打印 z;并第三次转换它,再花 2 纳秒。像这样,Java 解释器将转换打印 z;指令进入机器代码10次。

因此,解释器总共需要 10 x 2 = 20 纳秒才能完成此循环。此过程既费时又效率低。

这就是 JVM 不将此字节码指令分配给解释器的原因。它将此代码分配给 JIT 编译器。

在这里,术语编译器是指将Java虚拟机的指令集转换为特定处理器的指令集的转换器。

JIT 编译器如何执行循环指令?


让我们了解 Java 中的 JIT 编译器如何执行循环指令。

首先,JIT 编译器读取 print z 指令,然后将其转换为机器代码。为此,假设 JIT 编译器需要 2 纳秒才能完成此任务。

现在,JIT 编译器分配一个内存块,并将此机器代码指令推送到该内存中。为此,假设还需要 2 纳秒才能完成它。因此,JIT 编译器总共花费了 4 纳秒。

接下来,处理器将从内存中获取此机器代码指令并执行 10 次。

现在您可以观察到 JIT 编译器仅花费 4 纳秒即可完成执行,而解释器需要 20 纳秒才能执行相同的循环。

因此,JIT 编译器提高了执行过程的速度。


这里再次出现一个问题,为什么前两条指令不被JVM分配给JIT编译器。

原因很清楚。JIT 编译器转换每条指令需要 4 纳秒,而解释器实际上只需要 2 纳秒来转换每条指令。

当.class文件加载到内存中时,JVM首先尝试确定哪些代码要提供给解释器,哪些代码要提供给JIT编译器,以便性能更好。

提供给 JIT 编译器的代码块在 Java 中也称为热点。Java语言中的这个特性确实提高了程序在运行时的执行时间,特别是当它要多次执行时。

尽管不建议这样做,但也可以关闭 JIT 编译器选项。

因此,Java 解释器和 JIT 编译器同时工作,将字节码指令转换为机器码指令。

JVM中的垃圾回收器有助于清理未使用的内存,以提高程序的效率。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2008-08-21,如有侵权请联系 cloudcommunity@tencent 删除教程内存javajvm编译器

本文标签: 什么是 Java 中的 JVM