G1垃圾收集器入门教程(2)——Java技术和JVM

Java 概述

Java 是一种编程语言和计算平台,它是由 Sun 微系统公司于 1995 年首次发布的。Java 程序包括实用工具、游戏和商业应用等等,而 Java 正是驱动这些程序的底层技术。Java 在全世界大约 8.5 亿台个人电脑上运行,并且还在全世界数十亿台设备上运行,包括移动设备和电视设备。Java 由一些关键组件构成,它们组成一个整体,形成 Java 平台。

Java 运行时版本

当你下载 Java 时,你便能获得 Java 运行时环境(JRE)。JRE 由 Java 虚拟机(JVM)、Java 平台核心类,以及支持 Java 平台的库文件构成。如果想要在你的电脑上运行 Java 应用程序,那么这三个组件是必不可少的。可以通过 Java 7 编写多种应用程序:作为桌面应用直接在操作系统中运行的 Java 应用程序、使用 Java Web Start 从网络上下载安装的桌面应用程序、内嵌至浏览器的 Web 应用程序(使用 JavaFX)。

Java 编程语言

Java 是一种面向对象的编程语言,包含以下特性:

  • 平台无关性 —— Java 应用程序会被编译成字节码,存储在 class 文件之中,然后加载至 JVM。由于应用程序是在JVM中运行的,因此它们可以在很多不同的操作系统和设备上运行。
  • 面向对象 —— Java 是一种面向对象的编程语言,它借鉴了 C 和 C++ 的很多特性,并且进行了改进。
  • 自动垃圾收集 —— Java 会自动分配和回收内存,因此这项任务不会给程序带来负担。
  • 丰富的标准库 —— Java 包含海量的预制对象,它们可用于实现很多种功能,包括输入/输出、网络和日期操作。

Java 开发套件

Java 开发套件(JDK)是一套用于开发 Java 应用程序的工具集合。通过 JDK,你可以编译使用 Java 编程语言编写的程序,然后在 JVM 中运行。除此之外,JDK 还提供用于打包和分发应用程序的工具。

JDK 和 JRE 共享 Java 应用程序编程接口(Java API)。Java API 是一套预先打包的程序库集合,开发者可以使用它们来创建 Java 应用程序。Java API 提供了很多实用工具,可以帮助开发者简化很多常用的编程任务,包括字符串操作、日期/时间处理、网络通信,以及实现数据结构(例如:表(list)、映射(map)、栈(stack)和队列(queue))。

Java 虚拟机

Java 虚拟机(JVM)是一种抽象计算机。JVM 是一个看起来像计算机的程序,可用于执行 Java 程序。通过这种方式,开发者可以使用同一套接口和程序库来编写 Java 应用程序。每种操作系统都有各自具体的 JVM 实现,它们会将 Java 程序指令翻译成本地操作系统运行的指令和命令。通过这种方式,Java 程序便能够实现平台无关性。

Java 虚拟机的首个原型实现是由 Sun 微系统公司推出的,它模拟了安装在手持设备中的软件的 Java 虚拟机指令集,这些手持设备类似于同一时代的个人数字助理(PDA)。Oracle 的当前实现模拟了移动设备、桌面设备和服务器设备上的 Java 虚拟机,但是 Java 虚拟机并不会假定任何特定的实现技术、宿主机硬件或宿主机操作系统。JVM 并不总是解释执行的,也可以通过将它的指令集编译成指定 CPU 的指令集来实现。JVM 还可以使用微代码来实现,或者直接集成在硅芯片中实现。

Java 虚拟机对 Java 编程语言一无所知,只能识别特定的二进制格式,也就是 class 文件格式。class 文件包含 Java 虚拟机指令(或字节码)和符号表,除此之外,还有其他的辅助信息。

为了安全性起见,Java 虚拟机具有强大的语法,并且要求 class 文件中的代码具有结构化约束。然而,任何能够在一个有效的 class 文件中表述其功能的编程语言,用其编写的应用程序都可以在 Java 虚拟机中运行。为了实现一般可用性,也就是机器无关的平台,其他编程语言的实现者可以转向 Java 虚拟机,将其作为各自编程语言的传递载体。

探索 JVM 架构

Hotspot 体系结构

HotSpot JVM 拥有的体系结构能够为诸多特性和功能提供坚实的基础,并且支持实现高性能和大规模可伸缩部署的能力。例如,HotSpot JVM 的 JIT 编译器会进行动态优化的即时编译。换句话说,当 Java 应用程序正在运行时,JVM 会进行最优化决策,然后生成高性能的本地机器指令,这些指令针对于底层的系统体系结构。除此之外,通过 JVM 运行时环境和多线程垃圾收集器的成熟演进和持续工程,HotSpot JVM 即使在最大可用性的计算机系统上也具有很高的可伸缩性。

Hotspot JVM的体系结构

JVM 的主要组件包括类加载器、运行时数据区和执行引擎。

Hotspot 的关键组件

JVM 的跟性能相关的关键组件,在下图中以高亮显示:

Hotspot JVM的关键组件

当我们进行性能调优时,通常会聚焦于 JVM 的三个组件。堆是用来存储你的对象数据的内存区域。这个区域是由 JVM 启动时选择的垃圾收集器负责管理的。大多数的调优选项是和调整堆的大小相关的,你应该根据实际情况,选择最合适的垃圾收集器。虽然 JIT 编译器也会对性能造成较大的影响,但是较新版本的 JVM 很少需要对此进行调优。

性能调优基础

通常,在对某个 Java 应用程序进行调优时,一般会聚焦于两个主要目标之一:响应性或吞吐量。随着本教程的进展,我们将会回来参考这些概念。

响应性

响应性可以用来表示某个应用程序或系统对一个数据请求的响应速度。包括以下示例:

  • 桌面图形应用程序响应某个事件的速度。
  • 网站返回某个页面的速度。
  • 数据库返回查询结果的速度。

对于专注于响应性的应用程序来说,较大的停顿时间是不能接受的。响应性更加关心如何在尽可能短的时间之内对请求作出响应。

吞吐量

吞吐量专注于某个应用程序如何在一个特定的时间段内最大化地完成尽可能多的工作。吞吐量可能采用的度量方法,如下例所示:

  • 在给定时间内完成的事务数量。
  • 批处理程序在一个小时内能够完成的任务数量。
  • 应用程序在一个小时内能够完成的数据库查询次数。

对于注重吞吐量的应用程序来说,较高的停顿时间是可以接受的。因为高吞吐量的应用程序更加重视较长时间段之内的性能基准,所以快速的响应时间也就不是重点考虑的性能指标了。