• 获取不同虚拟机参数的终极方法


    在学习和实践虚拟机相关知识的过程中,经常会疑问某个特性在我现在用的版本中启用了么,需要手动配置启用么?当前虚拟机有700项左右的配置参数,不同版本和模式的虚拟机默认值也是不同的,不论是查文档或是网上搜索都很难快速的找到答案,最好的办法就是自己动手寻找答案。

    虚拟机类型

    在只考虑Oracle的HotSpot虚拟机时,区分不同虚拟机需要考虑大版本(1.6、1.7、1.8)、小版本(u43、u162)、位数(32、64)、模式(server、client),以上任意变化都可能导致默认参数的不同,在验证一些新特性时尽量保证服务器和本地环境一致。

    虚拟机模式

    虚拟机(HotSpot)有client和server两种模式,分别用 -client-server 参数启用。

    $ java -client -version
    
    java version "1.8.0_162"
    Java(TM) SE Runtime Environment (build 1.8.0_162-b12)
    Java HotSpot(TM) Client VM (build 25.162-b12, mixed mode)
    

    or

    $ java -server -version
    
    java version "1.8.0_162"
    Java(TM) SE Runtime Environment (build 1.8.0_162-b12)
    Java HotSpot(TM) Server VM (build 25.162-b12, mixed mode)
    

    client和server模式一些默认值有所不同,最明显的就是server模式(jdk1.8)默认使用吞吐量优先收集器(UseParallelGC)、默认打开逃逸分析(DoEscapeAnalysis),这些配置让server模式有更好的资源利用以及长期稳定运行支持。

    如果没有显式指定 -client-server 参数,虚拟机会根据运行环境是否服务器级别选择是否启用server模式,但是这让人很不放心;同时即使有时候显示指定该参数,由于当前安装版本不支持(例如jdk8u151的64位windows版本仅支持server模式),依然不会生效。如何能确认当前服务器上的虚拟机运行在server模式呢?答案是通过系统属性变量:

    System.out.println(System.getProperty("java.vm.name"));
    
    Java HotSpot(TM) Client VM
    or
    Java HotSpot(TM) 64-Bit Server VM
    

    查看配置的方法

    JDK1.6u21后HotSpot虚拟机提供了 -XX:+PrintFlagsFinal 用来查看最终生成的虚拟机配置参数,可以用在启动配置,甚至没有启动类时对 -version 生效(注意在有启动类时不要带 -version ,会阻挡执行后面的启动类)。

    java -server -XX:+PrintFlagsFinal -version
    

    它生的结果有5列:

    Type | Name | Operator | Value | Application
    

    如:

    java -server -XX:+PrintFlagsFinal -version | grep "UseSerialGC|UseG1GC|UseParallelGC|UseConcMarkSweepGC" 
    
    bool UseConcMarkSweepGC                       = false                              {product}
    bool UseG1GC                                  = false                              {product}
    bool UseParallelGC                            := true                                {product}
    bool UseSerialGC                              = false                              {product}
    

    其中需要注意第三列,:= 意味着值是被修改的,= 表示默认值,其他列对使用者意义不大。

    配合使用 -XX:+UnlockExperimentalVMOptions-XX:+UnlockDiagnosticVMOptions 可以解锁显示更多隐藏配置参数。

    类似命令 -XX:+PrintCommandLineFlags仅展示第三列为 := 的参数,即被修改或主动设置过的参数。

    类似命令 -XX:+PrintFlagsInitial仅展示第三列为 = 的参数,即默认值,意义不大。

    在使用实践过程中,发现 -client 模式下 PrintFlagsFinal 显示 UseSerialGC = false ,而实际上如果打印GC信息 -XX:+PrintGCDetails 会看到[DefNew: 4416K->512K...]这样的信息,即实际上该值为true,这是一项历史bug,在jdk9修复(因为默认使用g1收集器)。

    universe.cpp:
    
    727 else { // UseSerialGC
    728 // Don't assert that UseSerialGC is set here because there are cases
    729 // where no GC it set and we then fall back to using SerialGC.
    730 status = Universe::create_heap<GenCollectedHeap, MarkSweepPolicy>();
    731 }
  • 相关阅读:
    1052 卖个萌 (20 分)
    1046 划拳 (15 分)
    1051 复数乘法 (15 分)
    1042 字符统计 (20 分)哈希
    1041 考试座位号 (15 分)哈希
    1061 判断题 (15 分)
    1093 字符串A+B (20 分)简单哈希
    Hibernate框架
    SVN的安装与介绍
    easyUI的简单操作
  • 原文地址:https://www.cnblogs.com/pyx0/p/8594110.html
Copyright © 2020-2023  润新知