JVM类型与模式[java -version]

2016-08-17  本文已影响0人  DeleiGuo

本人博客原文:http://www.deleiguo.com/archives/172
转发请附带原文地址

简介

基本上一开始学习Java,就接触到第一个Java的命令:java -version
这个命令最常用的就是用来查看当前服务器的JDK环境版本,以此验证服务器环境变量是否已正确的设置好JDK。
最常见的结果一般有两种:

delei@DeleitekiMBP:~$ java -version
java version "1.7.0_79"
Java(TM) SE Runtime Environment (build 1.7.0_79-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)
root@ubuntu-server:~# java -version
java version "1.7.0_95"
OpenJDK Runtime Environment (IcedTea 2.6.4) (7u95-2.6.4-0ubuntu0.15.10.1)
OpenJDK 64-Bit Server VM (build 24.95-b01, mixed mode)

第一行:JDK的版本号
第二行:JDK的运行环境

但第三行是指的什么,在一开始没留意也不理解这一行包含着哪些信息,这里以Sun JDK为例来稍微深入看一下.

Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)

JVM类型

首先要知道的的是Server VM和Client VM可以理解是不同的虚拟机。
如果操作系统是64位的,只能是Server VM,Client VM只有在32位上才有。Oracle官方

Server VM和Client VM有什么区别?在官网的FAQ中有如下的描述:

JIT Compiler
1.What's the difference between the -client and -server systems?

These two systems are different binaries. They are essentially two different compilers (JITs)interfacing to the same runtime system. The client system is optimal for applications which need fast startup times or small footprints, the server system is optimal for applications where the overall performance is most important. In general the client system is better suited for interactive applications such as GUIs. Some of the other differences include the compilation policy,heap defaults, and inlining policy.

大致翻译:
这两个JVM采用不同的编译器。
Client JVM适合快速启动和较小内存的,它适合强调交互的应用,比如GUI(桌面级应用界面);
Server JVM则是偏重执行时候的效率的。
其他不同的地方"编译策略"、"默认堆大小"、"内嵌策略"

2.Where do I get the server and client systems?

Client and server systems are both downloaded with the 32-bit Solaris and Linux downloads. For 32-bit Windows, if you download the JRE, you get only the client, you'll need to download the SDK to get both systems.

For 64-bit, only the server system is included. On Solaris, the 64-bit JRE is an overlay on top of the 32-bit distribution. However, on Linux and Windows, it's a completely separate distribution.

主要内容翻译:
在32位的系统中,如果下载JRE,则只有client;
从Java SE 5.0开始,在64位的系统中,默认的时候Server,32位的默认

以上是从官方得到的原理/规范使用上的一些说明。接下来看在实际当中,如何切换Server VM和Client VM:

  1. 命令切换(推荐)
    在CMD/终端命令中,执行java -server -versionjava -client -version即可切换;

  2. 修改文件(永久切换)
    jre/lib/i386/(32位的JDK有i386文件夹),编辑修改jvm.cfg文件

# List of JVMs that can be used as an option to java, javac, etc.
# Order is important -- first in this list is the default JVM.
# NOTE that this both this file and its format are UNSUPPORTED and
# WILL GO AWAY in a future release.
#
# You may also select a JVM in an arbitrary location with the
# "-XXaltjvm=<jvm_dir>" option, but that too is unsupported
# and may not be available in a future release.
#
-client KNOWN
-server KNOWN
-hotspot ALIASED_TO -client
-classic WARN
-native ERROR
-green ERROR

# Order is important -- first in this list is the default JVM.
第一行的配置则为默认的JVM,这里第一行是-client,所有默认是Client VM;
要想用Server VM,则将第二行与第三行调换位置保存即可;

应用场景

  1. 我们时常会在开发/生产环境中对web 服务器调整JVM的参数,一般来说目前服务器都是64位的,可以先用java -version来查看环境;
  2. 根据应用的场景需要,在jvm中加上-server 参数;

JVM运行模式

在CMD/终端命令中,执行java -X

root@ubuntu-server:~# java -X
    -Xmixed           mixed mode execution (default)
    -Xint             interpreted mode execution only

在此可以知道mixed是默认的模式;
JVM模式有:-Xint, -Xcomp, 和 -Xmixed

在CMD/终端命令中,可以直接通过命令来切换模式:

root@ubuntu-server:~# java -Xint -version
java version "1.7.0_95"
OpenJDK Runtime Environment (IcedTea 2.6.4) (7u95-2.6.4-0ubuntu0.15.10.1)
OpenJDK 64-Bit Server VM (build 24.95-b01, interpreted mode)

root@ubuntu-server:~# java -Xcomp -version
java version "1.7.0_95"
OpenJDK Runtime Environment (IcedTea 2.6.4) (7u95-2.6.4-0ubuntu0.15.10.1)
OpenJDK 64-Bit Server VM (build 24.95-b01, compiled mode)

** 代码验证**
我们通过一个小的Java代码来验证下不同mode下的执行耗时(Server VM)

public class JVMModeTest {

    private static void test() {//循环++
        for (int i =0;i<1000000000;i++) {
        }
    }

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        test();
        long end = System.currentTimeMillis();
        System.out.println(end-start);//打印执行耗时
    }

}

结果如下:

root@ubuntu-server:~/work/java$ java -Xcomp JVMModeTest
2
root@ubuntu-server:~/work/java$ java -Xint JVMModeTest
28562
root@ubuntu-server:~/work/java$ java -Xmixed JVMModeTest
18

引用原文:深入理解Java虚拟机:JVM高级特性与最佳实践(第2版)

由于即时编译器编译本地代码需要占用程序运行时间,要编译出优化程度更高的代码,所花费的时间可能更长;而且想要编译出优化程度更高的代码,解释器可能还要替编译器收集性能监控信息,这对解释执行的速度也有影响。为了在程序启动响应速度与运行效率之间达到最佳平衡,HotSpot虚拟机还会逐渐启用分层编译(Tiered Compilation)[4]的策略,分层编译的概念在JDK 1.6时期出现,后来一直处于改进阶段,最终在JDK 1.7的Server模式虚拟机中作为默认编译策略被开启。分层编译根据编译器编译、优化的规模与耗时,划分出不同的编译层次,其中包括:

实施分层编译后,Client Compiler和Server Compiler将会同时工作,许多代码都可能会被多次编译,用Client Compiler获取更高的编译速度,用Server Compiler来获取更好的编译质量,在解释执行的时候也无须再承担收集性能监控信息的任务

注:
[1] 在虚拟机中习惯将Client Compiler称为C1,将Server Compiler称为C2。


参考/引用

http://my.oschina.net/itblog/blog/507822
http://ifeve.com/useful-jvm-flags-part-1-jvm-types-and-compiler-modes-2/
深入理解Java虚拟机:JVM高级特性与最佳实践(第2版)

http://www.oracle.com/technetwork/java/hotspotfaq-138619.html
http://docs.oracle.com/javase/7/docs/technotes/guides/vm/server-class.html

上一篇 下一篇

猜你喜欢

热点阅读