`

JVM实用参数(一)JVM类型以及编译器模式

阅读更多

原文地址:https://blog.codecentric.de/en/2012/07/useful-jvm-flags-part-1-jvm-types-and-compiler-modes/

译者:赵峰,iDestiny    校对:郭蕾

现在的JVM运行Java程序(和其它的兼容性语言)时在高效性和稳定性方面做的非常出色。自适应内存管理、垃圾收集、及时编译、动态类加载、锁优化——这里仅仅列举了某些场景下会发生的神奇的事情,但他们几乎不会直接与普通的程序员相关。在运行时,JVM会不断的计算并优化应用或者应用的某些部分。

虽然有了这种程度的自动化(或者说有这么多自动化),但是JVM仍然提供了足够多的外部监控和手动调优工具。在有错误或低性能的情况下,JVM必须能够让专家调试。顺便说一句,除了这些隐藏在引擎中的神奇功能,允许大范围的手动调优也是现代JVM的优势之一。有趣的是,一些命令行参数可以在JVM启动时传入到JVM中。一些JVM提供了几百个这样的参数,所以如果没有这方面的知识很容易迷失。这系列博客的目标是着重讲解日常相关的一些参数以及他们的适用场合。我们将专注于Java6的Sun/Oracle HotSpot JVM,大多数情况下,这些参数也会适用于其他一些流行的JVM里。

 

-server and -client

有两种类型的 HotSpot JVM,即”server”和”client”。服务端的VM中的默认为堆提供了一个更大的空间以及一个并行的垃圾收集器,并且在运行时可以更大程度地优化代码。客户端的VM更加保守一些(校对注:这里作者指客户端虚拟机有较小的默认堆大小),这样可以缩短JVM的启动时间和占用更少的内存。有一个叫”JVM功效学”的概念,它会在JVM启动的时候根据可用的硬件和操作系统来自动的选择JVM的类型。具体的标准可以在这里找到。从标准表中,我们可以看到客户端的VM只在32位系统中可用。

如果我们不喜欢预选(校对注:指JVM自动选择的JVM类型)的JVM,我们可以使用-server和-client参数来设置使用服务端或客户端的VM。虽然当初服务端VM的目标是长时间运行的服务进程,但是现在看来,在运行独立应用程序时它比客户端VM有更出色的性能。当应用的性能非常重要时,我推荐使用-server参数来选择服务端VM。一个常见的问题:在一个32位的系统上,HotSpot JDK可以运行服务端VM,但是32位的JRE只能运行客户端VM。

-version and -showversion

当我们调用“java”命令时,我们如何才能知道我们安装的是哪个版本的Java和JVM类型呢?在同一个系统中安装多个Java,如果不注意的话有运行错误JVM的风险。在不同的Linux版本上预装JVM这方面,我承认现在已经变的比以前好很多了。幸运的是,我们现在可以使用-version参数,它可以打印出正在使用的JVM的信息。例如:

$ java -version
java version "1.6.0_24"
Java(TM) SE Runtime Environment (build 1.6.0_24-b07)
Java HotSpot(TM) Client VM (build 19.1-b02, mixed mode, sharing)

输出显示的是Java版本号(1.6.0_24)和JRE确切的build号(1.6.0_24-b07)。我们也可以看到JVM的名字(HotSpot)、类型(client)和build ID(19.1-b02) )。除此之外,我们还知道JVM以混合模式(mixed mode)在运行,这是HotSpot默认的运行模式,意味着JVM在运行时可以动态的把字节码编译为本地代码。我们也可以看到类数据共享(class data sharing)是开启的,类数据共享(class data sharing)是一种在只读缓存(在jsa文件中,”Java Shared Archive”)中存储JRE的系统类,被所有Java进程的类加载器用来当做共享资源。类数据共享(Class data sharing)可能在经常从jar文档中读所有的类数据的情况下显示出性能优势。

-version参数在打印完上述信息后立即终止JVM。还有一个类似的参数-showversion可以用来输出相同的信息,但是-showversion紧接着会处理并执行Java程序。因此,-showversion对几乎所有Java应用的命令行都是一个有效的补充。你永远不知道你什么时候,突然需要了解一个特定的Java应用(崩溃时)使用的JVM的一些信息。在启动时添加-showversion,我们就能保证当我们需要时可以得到这些信息。

-Xint, -Xcomp, 和 -Xmixed

-Xint和-Xcomp参数和我们的日常工作不是很相关,但是我非常有兴趣通过它来了解下JVM。在解释模式(interpreted mode)下,-Xint标记会强制JVM执行所有的字节码,当然这会降低运行速度通常低10倍或更多。-Xcomp参数与它(-Xint)正好相反,JVM在第一次使用时会把所有的字节码编译成本地代码,从而带来最大程度的优化。这听起来不错,因为这完全绕开了缓慢的解释器。然而,很多应用在使用-Xcomp也会有一些性能损失,当然这比使用-Xint损失的少,原因是-xcomp没有让JVM启用JIT编译器的全部功能。JIT编译器在运行时创建方法使用文件,然后一步一步的优化每一个方法,有时候会主动的优化应用的行为。这些优化技术,比如,积极的分支预测(optimistic branch prediction),如果不先分析应用就不能有效的使用。另一方面方法只有证明它们与此相关时才会被编译,也就是,在应用中构建某种热点。被调用很少(甚至只有一次)的方法在解释模式下会继续执行,从而减少编译和优化成本。

注意混合模式也有他自己的参数,-Xmixed。最新版本的HotSpot的默认模式是混合模式,所以我们不需要特别指定这个标记。我们来用对象填充HashMap然后检索它的结果做一个简单的用例。每一个例子,它的运行时间都是很多次运行的平均时间。

$ java -server -showversion Benchmark
java version "1.6.0_24"
Java(TM) SE Runtime Environment (build 1.6.0_24-b07)
Java HotSpot(TM) Server VM (build 19.1-b02, mixed mode)
 
Average time: 0.856449 seconds
$ java -server -showversion -Xcomp Benchmark
java version "1.6.0_24"
Java(TM) SE Runtime Environment (build 1.6.0_24-b07)
Java HotSpot(TM) Server VM (build 19.1-b02, compiled mode)
 
Average time: 0.950892 seconds
$ java -server -showversion -Xint Benchmark
java version "1.6.0_24"
Java(TM) SE Runtime Environment (build 1.6.0_24-b07)
Java HotSpot(TM) Server VM (build 19.1-b02, interpreted mode)
 
Average time: 7.622285 seconds

当然也有很多使-Xcomp表现很好的例子。特别是运行时间长的应用,我强烈建议大家使用JVM的默认设置,让JIT编译器充分发挥其动态潜力,毕竟JIT编译器是组成JVM最重要的组件之一。事实上,正是因为JVM在这方面的进展才让Java不再那么慢。

分享到:
评论

相关推荐

    JVM 实用参数系列 - v1.0.pdf

    JVM 是 Java Virtual Machine(Java 虚拟机)的缩写,Java 通过使用 Java 虚拟机屏蔽了与具体平台相关的 信息,使得 Java...JVM 实用参数系列一共包括八篇文章,由浅入深,从编译器、垃圾回 收、内存调优等方面介绍 JVM。

    GraalVM是一个为JVM开发了一个新的JIT编译器和Polyglot运行时

    GraalVM是一个基于Oracle Labs的项目,为JVM开发了一个新的JIT编译器和Polyglot运行时。

    Swift-to-JVM字节码编译器JetANTLR.zip

    Jet 是 Swift-to-JVM 字节码编译器,为 Java 8 Runtime 而准备。Jet 使用 ANTLR 编写。 标签:JetANTLR

    jvm指令手册 +JVM必知必会,掌握虚拟机编译过程.rar

    JVM是Java Virtual ...i开头的指令操作数类型是integer类型,l开头的指令操作数类型是long类型,f开头的指令操作数类型是float类型,d开头的指令操作数类型是double,a开头的指令操作数类型是引用类型(reference)

    用Java写成的Tiger到JVM编译器

    使用Java写成的Tiger到JVM编译器。 前端代码使用SableCC自动生成,框架清晰。 后端JVM汇编和class文件生成使用ASM库进行。 该编译器按BSD协议授权。

    基于JVM字节码类似Kotlin语言的编译器.zip

    【项目资源】: 包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。 ... 【项目质量】: 所有源码都经过严格测试,...

    21丨深入JVM即时编译器JIT,优化Java编译.html

    21丨深入JVM即时编译器JIT,优化Java编译.html

    JVM、Java编译器和Java解释器1

    Java编译器:将Java源文件(.java文件)编译成字节码文件(.class文件,是特殊的二进制文件,二进制字节码文件),这种字节码就是JVM的“机器语言”

    Java虚拟机JVM性能优化(二):编译器

    主要介绍了Java虚拟机JVM性能优化(二):编译器,本文先是讲解了不同种类的编译器,并对客户端编译,服务器端编译器和多层编译的运行性能进行了对比,然后给出了几种常见的JVM优化方法,需要的朋友可以参考下

    JVM 相关知识的脑图介绍

    JVM(Java虚拟机)是Java程序的运行环境,它是一个虚拟的计算机,负责将Java字节码解释成机器码并执行。JVM提供了内存管理、垃圾回收、安全性等功能,使得Java程序具有跨平台性。JVM的结构包括类加载器、解释器、...

    30道JVM综合面试题详解含答案(值得珍藏)

    JVM是Java Virtual Machine(Java虚拟机)的缩写,它是一种用于计算设备的规范,是一个虚构出来的计算机。JVM屏蔽了与具体操作系统平台相关的信息,使Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就...

    莫枢:JVM是多语言的平台

    Oracle JVM编译器团队工程师莫枢在《JVM——多语言的平台》的演讲中,提到Java最强悍的地方在于编译器非常便于应用。而最初定位在为Java提供丰富的功能平台JVM后期走了更为宽广的路线,支持更多的独立语言。有微博...

    rakudo, 在MoarVM和JVM上,Rakudo Perl 6: Perl 6.zip

    rakudo, 在MoarVM和JVM上,Rakudo Perl 6: Perl 6 Rakudo 6这是 Rakudo Perl 6,它是MoarVM和JVM的一个 Perl 6编译器。Rakudo 6是版权 © 2008 -2018,Perl基金会。 Rakudo Perl 6是在艺术许可以证 2.0条款下分发的...

    oberonc:用于JVM的Oberon-07编译器

    尽管为堆栈机生成代码很简单,但是复杂的类文件格式以及考虑到Java语言设计JVM的事实使这一任务更加恶化。 实际上,JVM缺少支持Oberon功能所需的许多原语,特别是: 值类型 通过参考评估策略 过程变量(指向函数的...

    JVM中编译Class、内存回收、多线程原理和使用

    JVM负责装载class文件并执行,因此,首先是JDK如何将Java代码编译为class文件、如何装载class文件及如何执行class,将源码编译为class文件的实现取决于各个JVM实现或各种源码编译器。class文件通常由类加载器...

    JVM.JS-Compiler:JVM.JS的编译器

    JVM.JS编译器 这是JVM.JS Java到JavaScript编译器和运行时框架的组件。 执照 JVM.JS的此组件已通过LGPLv3许可

    这些不可不知的JVM知识.pdf

    JVM 的全称是 「Java Virtual Machine」,也就是我们耳熟能详的 Java 虚拟机。 JVM具备着计算机的基本运算方式,它主要负责把 Java 程序生成的字节码文件,解释成具体系统平台上的机器指令,让其在各个平台运行。 ...

    编程文档JVM、Java基础、.rar

    JVM基础 jvm:运行在操作系统上的假想的计算机 Java文件的编译和解释 JVM组成 GC回收算法 Java引用,GC垃圾收集器,OOM 类加载,类加载器 对象初始化 编译 JiT:即时编译 两大无关性 平台无关性: 每一台平台解释器...

    深入JVM即时编译器JIT,优化Java编译

    说到编译,我猜你一定会想到 .java 文件被编译成 .class 文件的过程,这个编译我们一般称为前端编译。Java 的编译和运行过程非常复杂,除了前端编译,还有运行时编译。由于机器无法直接运行 Java 生成的字节码,所以...

Global site tag (gtag.js) - Google Analytics