《Java学习指南》—— 1.2 虚拟机

简介: 基于历史的原因,往往认为解释器很慢,但是由于Java并非传统的解释语言。除了将源代码编译为可移植的字节码,Java还得到了精心的设计,通过将字节码动态编译为本地机器码,使得运行时系统的软件实现可以对其性能进行优化。

本节书摘来异步社区《Java学习指南》一书中的第1章,第1.2节,作者:【美】Patrick Niemeyer , Daniel Leuck,更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.2 虚拟机

Java既是一种编译语言也是一种解释语言。Java源代码将被转换为简单的二进制指令,这与通常的微处理器机器码非常类似。不过,C或C++ 源代码要针对特定处理器模型而优化为本地指令,而Java源代码却均会编译为一种通用格式,即面向虚拟机的指令。

已编译Java字节码由一个Java运行时解释器执行。运行时系统可以完成一个实际处理器所做的所有正常操作,但是会在一个安全的虚拟环境中完成这些工作。它会执行一个基于栈的指令集,并像操作系统一样管理内存。运行时系统将创建并操作基本(primitive)数据类型,另外加载和调用新近引用的代码块。最重要的是,所有这些都是遵循一个严格定义的开放规范完成的,任何人如若希望生成一个与Java兼容的虚拟机,都可实施此规范。综合来看,虚拟机和语言定义则提供了一个完整的规范。这样,基本Java语言的所有特性都得到了义,而且与实现无关。例如,Java指定了所有基本数据类型的大小,而不是将其留待平台实现来确定。

Java解释器是相对轻量级的,而且规模较小,它可以实现为某种特定平台所需的任何一种形式。解释器可以作为一个单独的应用运行,也可以嵌入到另一个软件中(如Web浏览器)。综合起来看,这意味着Java代码隐含的就是可移植的。同样的Java应用程序的字节码,可以运行在提供了Java运行时环境的任何平台上,如图1-1所示。你不需要为了不同的平台而提供应用程序的其他版本,并且你不必把源代码分发给用户。

92bd719c11ea87f0c57fc1ab2e67d2fd04a0fa09

Java代码的基本单位是类。与其他面向对象语言类似,类是包含可执行代码和数据的应用组件。已编译的Java类采用一种通用的二进制格式发布,其中包含有Java字节码和其他类信息。类可以分散地加以维护,并保存于本地的文件或归档文件中,也可以保存在网络服务器上。应用需要类时,将在运行时动态地进行定位和加载。

除了特定于平台的运行时系统外,Java还有大量的基本类,其中包含有依赖于架构的方法。这些本地方法(native method)相当于Java虚拟机和真实世界之间的网关。它们在主机平台上以一种本地编译语言实现,并提供对网络、窗口系统和主机文件系统等资源的低层级访问。然而,Java的主要部分则完全用Java编写的,都是从这些基本部分演化而来,因此是可移植的。这包括基本Java工具,如Java编译器、网络和GUI库,它们都采用Java编写,因此在所有Java平台上均可以下同的方式使用而不需要移植。

基于历史的原因,往往认为解释器很慢,但是由于Java并非传统的解释语言。除了将源代码编译为可移植的字节码,Java还得到了精心的设计,通过将字节码动态编译为本地机器码,使得运行时系统的软件实现可以对其性能进行优化。这也称为即时(Just-In-Time,JIT)编译或动态编译。利用JIT编译,Java代码可以与本地已编译代码执行得一样快,同时还可保持其可传输性和安全性。

对于力图比较语言性能的人来说,这往往是一个误区。已编译Java代码只是由于安全性和虚拟机设计(数组越界检查)而导致运行时性能有所下降,而这也是性能下降的唯一的内在因素。而其他的所有内容都可以优化为本地码,这一点与静态编译语言所能做的并无二致。除此之外,较之于其他语言,Java语言还包括了更多的结构化信息,这样就为优化提供了更大的空间。还要记住,这些优化可以在运行时完成,即可以考虑到实际的应用特性。那么什么工作更适合于在编译时完成而不是运行时完成呢?在此有一个权衡,即时间。

传统JIT编译的问题在于,优化代码会花费时间。因此,JIT编译器可以得到很好的结果,但是,在应用程序启动的时候会有显著的延迟。对于长时间运行的服务器端应用程序来说,这通常不是个问题,而对于在计算能力有限的较小设备上运行的客户端软件和应用程序来说,这却是一个严重的问题。为了解决这个问题,Java的编译器技术(称为HotSpot)使用了一种叫做自适应编译(adaptive compilation)的技巧。如果仔细查看程序究竟花费时间做了哪些工作,可以发现它们往往会把绝大部分时间用于反复执行一部分代码。这一反复执行的代码块可能仅仅是整个程序中很小的一部分,但是其表现却决定了整个程序的性能。自适应编译还允许Java运行时利用一些新的类型的优化,而这些优化在一种静态编译型语言中是无法做到的,因此,Java代码号称在某些情况下可以比C/C++运行得更快。

为了充分利用这一事实,HotSpot仍以一个正常的Java字节码解释器“出场”,但在此存在一个区别:它在执行代码时要对代码进行测量(探查),从而查看哪些部分得到了重复执行。一旦获知对于性能有关键影响的代码部分,HotSpot将把这些代码段编译为真正的机器码。由于它只是将程序的一小部分编译为机器码,因此就有足够的时间对这一部分加以优化。程序余下的部分则根本无需编译,只要进行解释即可,这样可以节省内存和时间。实际上,Java VM(虚拟机)可以以两种模式运行:客户端和服务器,这分别决定了重点究竟是快速的启动时间以及节省内存还是最佳的性能。

此时,一个自然而然的问题是,为何每次一个应用程序关闭的时候,要丢弃这些很好的探查信息?Sun在发布Java 5.0的时候,将共享的、只读的类持久地存储到一个优化后的表单中,从而部分地回答了这个问题。这显著地减少了启动时间,以及在一台给定的机器上运行多个Java应用程序的负担。实现这一点的技术很复杂,但是,思路很简单:即优化程序中需要快速运行的部分,而不需要担心其他的部分。

本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。

相关文章
|
2月前
|
存储 Java 数据安全/隐私保护
【JVM】Java虚拟机栈(Java Virtual Machine Stacks)
【JVM】Java虚拟机栈(Java Virtual Machine Stacks)
38 0
|
11天前
|
存储 Java
深入理解Java虚拟机:JVM内存模型
【4月更文挑战第30天】本文将详细解析Java虚拟机(JVM)的内存模型,包括堆、栈、方法区等部分,并探讨它们在Java程序运行过程中的作用。通过对JVM内存模型的深入理解,可以帮助我们更好地编写高效的Java代码,避免内存溢出等问题。
|
2月前
|
缓存 算法 安全
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍(二)
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍
21 0
|
2月前
|
缓存 Java C#
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍(一)
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍
90 0
|
4月前
|
Linux Windows
FinalShell连接Linux虚拟机报错java.net.ConnectException: Connection timed out: connect(亲测有效)
FinalShell连接Linux虚拟机报错java.net.ConnectException: Connection timed out: connect(亲测有效)
196 0
|
2月前
|
存储 Java 开发者
深入理解Java虚拟机(JVM)内存管理
【2月更文挑战第11天】 在本篇文章中,我们将深入探讨Java虚拟机(JVM)的内存管理机制,一项对于优化Java应用性能至关重要的技术领域。不同于常规的技术文章摘要,我们不仅概述了JVM内存管理的基本概念,还将引导读者通过实际案例理解其在现实世界应用中的重要性。从堆(Heap)和栈(Stack)的区别开始,到垃圾收集(Garbage Collection)机制的工作原理,本文旨在为Java开发者提供一个清晰、系统的JVM内存管理知识框架,帮助他们在开发过程中做出更加明智的决策。
|
3月前
|
存储 算法 Java
Java虚拟机内存管理机制
【2月更文挑战第7天】本文主要介绍了Java虚拟机内存管理机制的基本原理和实现方式。Java虚拟机的内存管理机制是Java程序运行的重要组成部分,对程序性能和稳定性有着直接的影响。文章首先从Java虚拟机内存模型入手,介绍了Java虚拟机中堆内存、方法区、栈、PC寄存器等内存区域的功能特点和使用方式;然后详细阐述了Java虚拟机内存管理机制的垃圾回收算法和回收器的分类、优化和实现过程;最后介绍了一些常见的内存问题和优化技巧,以及如何通过代码调优和合理使用内存配置参数来提高程序的性能和稳定性。
|
4月前
|
安全 前端开发 Java
【JVM】<Java虚拟机>JVM架构&各种**虚拟机
【1月更文挑战第26天】【JVM】<Java虚拟机>JVM架构&各种**虚拟机
|
4月前
|
自然语言处理 Oracle Java
【JVM】<Java虚拟机>JVM和JAVA体系结构
【1月更文挑战第26天】【JVM】<Java虚拟机>JVM和JAVA体系结构
|
4月前
|
算法 搜索推荐 Java
太实用了!阿里内部强推的超全Java算法学习指南,已被彻底征服
算法和数据结构一直以来都是程序员的基本内功。 数据结构可以看作是算法实现的容器,通过一系列特殊结构的数据集合,能够将算法更为高效而可靠地执行起来。