深入拆解Java虚拟机(一)

1. 为什么 Java 需要运行时环境 1.1. Java 程序的启动方式 IDE中启动,比如:Eclipse、IntelliJ IDEA 构建为 jar,通过命令行的方式启动,比如:java -jar application.jar 使用构建工具(如:Gradle、Maven)启动,比如 SpringBoot 应用启动:gradle bootRun、mvn spring-boot:run 1.2. JRE 是什么 在这里引用极客时间课程Java核心技术面试精讲中的一段话 我们日常会接触到 JRE(Java Runtime Environment) 或者 JDK(Java Development Kit)。JRE,也就是 Java 运行时环境,仅包含运行 Java 程序的必须组件,包括 Java 虚拟机以及 Java 核心类库等。而 JDK 可以看作是 JRE 的一个超集,提供了更多工具,比如编译器、各种诊断工具等。 1.3. 为什么需要运行时环境 不是有这么一句话么,计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决。话说回来,Java 代码运行之所以需要运行时环境,主要是由于以下几个方面的原因: Java 语言语法非常复杂,抽象程度高,直接在硬件上运行这种复杂的程序并不现实(并不是不可以,但是这样造成与相应硬件的强耦合,且不便于抽象和复杂语法的实现。),所以需要在运行之前进行一番转换。 实现平台无关性、做到 “Write once, run anywhere”,获得跨平台的能力。这样便需要一个中间层进行解耦,达到上层统一编码、下层跨越平台、中间实现兼容(所以,Java 语言的跨平台特性是由 Java 运行时环境实现的。也就是在不同平台皆有与之相对应的 Java 运行时环境,实现相同定义、不同实现。这样的思想是不是很熟悉,当然,这仅是我的理解)。 提供托管环境(Managed Runtime),该托管环境可以代替我们处理一些通用的、容易出错的、高难度的行为,比如自动内存管理、垃圾回收、安全权限动态检测等。 2. Java 代码在虚拟机中是怎样运行的 2.1. 虚拟机视角 执行 Java 代码首先需要将它编译而成的 class 文件加载到 Java 虚拟机中,加载后的 Java 类会被存放到方法区中。实际运行时,虚拟机会执行方法区内的代码(需要将字节码翻译为机器码,在 HotSpot 实现中,有解释执行和即时编译两种)。...

November 24, 2020 · 1 min · Fuyi

jvm 基础入门

前言 老生长谈,Java是一个什么事物,都有些什么样的特性呢? Java:Java 是一种广泛使用的计算机编程语言,拥有跨平台、面向对象、泛型编程的特性,广泛应用于企业级Web应用开发和移动应用开发。 Java 编程语言的风格十分接近C++语言。继承了C++语言面向对象技术的核心,舍弃了容易引起错误的指针,以引用取代;移除了C++中的运算符重载和多重继承特性,用接口取代;增加垃圾回收器功能。在Java SE 1.5版本中引入了泛型编程、类型安全的枚举、不定长参数和自动装/拆箱特性。Sun微系统对 Java语言 的解释是:“Java 编程语言是个简单、面向对象、分布式、解释性、健壮、安全与系统无关、可移植、高性能、多线程和动态的语言”。 Java 不同于一般的编译语言或解释型语言。它首先将源代码编译成字节码,再依赖各种不同平台上的虚拟机来解释执行字节码,从而具有“一次编写,到处运行”的跨平台特性。在早期 JVM 中,这在一定程度上降低了 Java 程序的运行效率。但在J2SE1.4.2发布后,Java 的运行速度有了大幅提升。 以上内容来自于维基百科,给定了 Java 一个明确的定义,但是对于Java平台以及特性并没有很好的归结,下面是我截取自极客时间Java核心技术面试精讲的部分内容: Java 本身是一种面向对象的语言,最显著的特性有两个方面,一是所谓的“书写一次,到处运行”(Write once, run anywhere),能够非常容易地获得跨平台能力;另外就是垃圾收集(GC, Garbage Collection),Java 通过垃圾收集器(Garbage Collector)回收分配内存,大部分情况下,程序员不需要自己操心内存的分配和回收。 我们日常会接触到 JRE(Java Runtime Environment)或者 JDK(Java Development Kit)。 JRE,也就是 Java 运行环境,包含了 JVM 和 Java 类库,以及一些模块等。而 JDK 可以看作是 JRE 的一个超集,提供了更多工具,比如编译器、各种诊断工具等。 对于“Java 是解释执行”这句话,这个说法不太准确。我们开发的 Java 的源代码,首先通过 Javac 编译成为字节码(bytecode),然后,在运行时,通过 Java 虚拟机(JVM)内嵌的解释器将字节码转换成为最终的机器码。但是常见的 JVM,比如我们大多数情况使用的 Oracle JDK 提供的 Hotspot JVM,都提供了 JIT(Just-In-Time)编译器,也就是通常所说的动态编译器,JIT 能够在运行时将热点代码编译成机器码,这种情况下部分热点代码就属于编译执行,而不是解释执行了。 在维基百科给出的定义中,提到 Java 编程语言是解释性的语言,而在Java核心技术面试精讲中提出该说法不太准确,我比较认可后者的看法。类似 JIT、AOT(Ahead-of-Time Compilation,在执行前直接将字节码编译成机器代码,静态编译) 技术的出现以及实践,使得 Java 的解释性变得不那么纯粹,此时从不同的角度可能会得到不同的结果,比如从占比上考虑,那么 Java 还是解释性的;如果从 JIT 的角度看,此刻的 Java 是编译性的;而从总体的角度来看,则是混合性的(解释和编译的混合)。...

November 10, 2020 · 7 min · Fuyi