你编写的Java代码是咋跑起来的?

如果你是一名 Java 开发人员,你肯定指定 Java 代码有很多种不同的运行方式。比如说可以在开发工具(IDEA、Eclipse等)中运行,可以双击执行 jar 文件运行,也可以在命令行中运行,甚至可以在网页(比如各种 OJ)中运行。当然,这些执行方式都离不开 JRE(Java 运行时环境)。

JRE 包含运行 Java 程序的必需组件,包括 JVM(Java 虚拟机)以及 Java 核心类库等。Java 程序员经常接触到的 JDK(Java 开发工具包)同样包含了 JRE,并且还附带了一系列开发、诊断工具。

本篇文章主要针对以下两个问题和大家一起探讨:

  1. 为什么需要 JVM?
  2. JVM 是怎样运行 Java 代码的呢?

为什么需要 JVM?

Java 一个非常重要的特点就是与平台的无关性,而使用 JVM 是实现这一特点的关键。Java 作为一门高级程序语言,语法复杂,抽象程度高。因此,直接在硬件上运行这种复杂的程序并不现实。所以在运行 Java 程序之前,我们需要对其进行转换。

设计一个面向 Java 语言特性的虚拟机,并通过编译器将 Java 程序转换成该虚拟机所能识别的指令序列(因为 Java 字节码指令的操作码(opcode)被固定为一个字节,故又称 Java 字节码)。

JVM 一般是在各个现有平台(如 Windows、Linux)上提供软件实现,这样可以使一旦一个程序被转换成 Java 字节码,那么便可以在不同平台上的虚拟机实现里运行(一次编写,到处运行)。

JVM 另外一个好处是带有托管环境(Managed Runtime),托管环境能够代替处理一些代码中冗长而且容易出错的部分,其中包括自动内存管理与垃圾回收(GC)。

另外,托管环境还提供了诸如数组越界、动态类型、安全权限等等的动态检测,使我们免于书写这些无关业务逻辑的代码。

JVM 是怎样运行 Java 代码的呢?

JVM 具体是怎么运行 Java 字节码的呢?下面我们一起来看一下:

从 JVM 来看,执行 Java 代码首先需要将它编译而成的 class 文件加载到 JVM 中。加载后的 Java 类会被存放于方法区(Method Area)中。实际运行时,JVM 会执行方法区内的代码。

JVM 会在内存中划分出堆和栈来存储运行时数据,JVM 会将栈细分为面向 Java 方法的 Java 方法栈,面向本地方法(用 C++ 写的 native 方法)的本地方法栈,以及存放各个线程执行位置的 PC 寄存器。

在运行过程中,每当调用进入一个 Java 方法,JVM 会在当前线程的 Java 方法栈中生成一个栈帧,用以存放局部变量以及字节码的操作数。栈帧的大小是提前计算好的,而且 JVM 不要求栈帧在内存空间里连续分布。

当退出当前执行的方法时,不管是正常返回还是异常返回,JVM 均会弹出当前线程的当前栈帧,并将之舍弃。

从硬件视角来看,Java 字节码无法直接执行。因此,JVM 需要将字节码翻译成机器码。

在 HotSpot 里面,上述翻译过程有两种形式:第一种是解释执行(interpreter),即逐条将字节码翻译成

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

后端核心技术精讲 文章被收录于专栏

专注分享后端技术干货,包括 Java 基础、Java 并发、JVM、Elasticsearch、Zookeeper、Nginx、微服务、消息队列、源码解析、数据库、设计模式、面经等,助你编程之路少走弯路。

全部评论
原创不易,欢迎点赞、收藏、订阅三连!
点赞 回复 分享
发布于 2020-04-05 18:25

相关推荐

码农索隆:小同学,看看我查看图片
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务