[转]你所不知道的五件事情--JVM的命令行选项

2023-11-21 07:18

本文主要是介绍[转]你所不知道的五件事情--JVM的命令行选项,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这是Ted Neward在IBM developerWorks中5 things系列文章中的一篇,讲述了关于JVM命令行参数的一些应用窍门,值得大家学习。(2010.09.01最后更新)

摘要:Java虚拟机有数百个命令行选项,只有经验十分丰富的Java开发员才会使用这些选项去调优Java运行时环境。学习如何监控并记录编译器性能,禁用显示的垃圾收集(System.gc()),扩展JRE,及其它。

    JVM是Java应用程序功能与性能背后的实际工作者,大部分Java开发者认为这是理所当然的。然而我们中很少有人真正地理解JVM是如何做到这些事的--如,分配并收集垃圾对象,摆弄线程,打开及关闭文件,解释和/或使用JIT编译Java字节码,以及其它任务。
    不熟悉JVM不仅会使你在应用程序的性能方面付出代价,而且当JVM出了某些问题时,还很难进行修复。
    5 things系列的这篇文章介绍一些好用的命令行JVM选项,你可以使用它们去诊断并调优Java虚拟机的性能。

1. DisableExplicitGC
    我无法告诉你我已经多少次被要求就应用程序性能问题进行咨询了,而我只是简单地对代码文件执行grep命令就能发现如清单1所示的程序--这就是早期Java性能的反模式:

Listing 1. System.gc();

//  We just released a bunch of objects, so tell the stupid
//  garbage collector to collect them already!
System.gc();

显式地执行垃圾收集器确实是个坏主意--这就像把你自己与一个疯狂的斗牛犬锁在电话亭中那样。虽然该调用的确切语义依赖于具体的实现,但假设你的JVM运行着一个分代垃圾收集器(大多数JVM也正是如此),System.gc()方法强制要求VM对Heap进行"全面清扫",即便有些并不是必要的。一般地,全面清扫的开销要比常规GC操作要大几个数量级,而常规GC操作的开销只会产生纯数学的负作用。
     但不要相信我的话--为了这个特殊的人为错误,Sun的工程师们为我们提供了一个JVM选项:-XX:+DisableExplicitGC选项自动地将System.gc()调用置为无用操作,给你一个机会去执行程序,并让你自己看看System.gc()是否已经帮助或损害整个JVM的执行。

2. HeapDumpOnOutOfMemoryError
    你肯定曾经遇到过JVM不断死掉的情况,即抛出OutOfMemoryError,在你的一生中似乎都不能设置一个调试器去捕获这个错误,并看看是出了什么问题?像这些不时发生且/或无法确定的问题能使一个开发员完全疯掉。
    你所想的,就是在在JVM快死掉时能够捕获Heap的快照--这正是命令-XX:+HeapDumpOnOutOfMemoryError所要做的。
    运行该命令就是告诉JVM创建一个"Heap转储快照",并将它保存为一个文件以便于处理,常常使用jhat工具(在前一篇文章中我有介绍过)。使用相应的命令-XX:HeapDumpPath,就指定被保存文件的确切路径。(不论文件保存在何处,要先确保文件系统和/或Java进程有必要的仅限配置能在那儿写文件。) 

3. bootclasspath
    偶尔地,将某个类,该类不同于原有的或以某种方式扩展而得到的JRE所存储的类,置于类路径中是有用的。(一个例子就是新的Java Crypto API适配器)。如果你想扩展JRE,那么你的定制实现需要能用于引导ClassLoader,该ClassLoader会加载java.lang.Object以及它在rt.jar中的所有同族成员。
    尽管你可以打开rt.jar并将你定制实现或新的包放入其中,但在技术上这就违反了当初你在下载JDK时所同意的协议。
    相反地,应该使用JVM自己的-Xbootclasspath选项,以及它的兄弟选项-Xbootclasspath/p-Xbootclasspath/a
    -Xbootclasspath允许你设置整个引导类路径,该路径一般地必须包含一个针对rt.jar的引用,再加上一批随JDK发布但不是rt.jar一部分的其它JAR文件。-Xbootclasspath/p会向已有引导类路径中预置值,然后-Xbootclasspath/a会将它连接起来。
    例如,如果你已经修改了原有的java.lang.Integer,并将修改后的程序放入子目录,mods,然后参数-Xbootclasspath/a mods将会在加载原有默认Integer类之前加载这个新的Integer实现。

4. verbose
    对于任何类型的Java应用,-verbose都是头等有用的诊断工具。该选项有三个子选项:gcclassjni
    一般地,如果JVM垃圾收集器在运行并导致了低下的性能,那么gc就是开发员们第一次想要弄清楚的地方。不幸地是,解释gc的输出需要些技巧,这足够成为一整本书的主题了。更糟地是,在命令行窗口打印出的输出对于不同的Java发行版是不同的,或者对于不同的JVM也是不同的,这造成难以对其进行正确地解释。
    一般来说,如果垃圾收集器是分代收集器(大多数"企业级"VM正是如此),会有一些布尔型选项去指定是否使用完全清除;在Sun的JVM中,这样的选项会以[Full GC ...]的形式出现在GC输出行的开头。
    class会是一个生命保护者,它尝试着诊断ClassLoader和/或不匹配的类冲突。它不仅会报告类是在何时被加载的,而且也会报告类是从何处被加载的,包括JAR文件的路径,如果这个类来自于一个JAR的话。
    jni很少用到,除非你有使用JNI和原生库。当启用该选项时,它会报告各种JNI事件,例如原生库何时被加载的,以及方法何时被绑定的;另外,该报告输出会由于不同的Java版或JVM实现而不尽相同。

5. 命令行-X
    我已经列出了一些JVM提供的且我比较喜欢的命令行选项,但还有更多的选项你自己就能发现到。运行命令行参数-X列出所有JVM支持的非标准的(但多数就是安全的)参数--就像这些:
    -Xint,使JVM以解释模式进行运行(对于测试JIT编译器是否真的作用到你的程序,或是证明你是否有Bug在JIT编译器中,该选项是很用的)。
    -Xloggc:,该参数所做的与-verbose:gc相同,但它会把日志记录到一个文件中,而不是一股脑地输出在命令窗口中。
    JVM命令行选项改了一次又一次,所以隔一段时间再去看会是一个好主意。这种区别就好像是,花上一整夜金城汤池盯着你的显示器,或者是下午五点就回家与爱人和孩子享用美餐(或是在Mass Effect 2中屠杀敌人,这取决于你的偏好)。

结论
    命令行选项的本意不是为了在产品环境中永久使用--事实上,除了你(可能)最终用于调优JVM垃圾收集器的选项之外,非标准的命令选项都不会被刻意地用到产品中。但作为能够窥探到完全不透明的虚拟机的内部工部情形的工具,它们是无价的。
    5 things系列的下一篇文章:Java日常工具。

这篇关于[转]你所不知道的五件事情--JVM的命令行选项的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/400730

相关文章

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

Java枚举类实现Key-Value映射的多种实现方式

《Java枚举类实现Key-Value映射的多种实现方式》在Java开发中,枚举(Enum)是一种特殊的类,本文将详细介绍Java枚举类实现key-value映射的多种方式,有需要的小伙伴可以根据需要... 目录前言一、基础实现方式1.1 为枚举添加属性和构造方法二、http://www.cppcns.co

Elasticsearch 在 Java 中的使用教程

《Elasticsearch在Java中的使用教程》Elasticsearch是一个分布式搜索和分析引擎,基于ApacheLucene构建,能够实现实时数据的存储、搜索、和分析,它广泛应用于全文... 目录1. Elasticsearch 简介2. 环境准备2.1 安装 Elasticsearch2.2 J

Java中的String.valueOf()和toString()方法区别小结

《Java中的String.valueOf()和toString()方法区别小结》字符串操作是开发者日常编程任务中不可或缺的一部分,转换为字符串是一种常见需求,其中最常见的就是String.value... 目录String.valueOf()方法方法定义方法实现使用示例使用场景toString()方法方法

Java中List的contains()方法的使用小结

《Java中List的contains()方法的使用小结》List的contains()方法用于检查列表中是否包含指定的元素,借助equals()方法进行判断,下面就来介绍Java中List的c... 目录详细展开1. 方法签名2. 工作原理3. 使用示例4. 注意事项总结结论:List 的 contain

Java实现文件图片的预览和下载功能

《Java实现文件图片的预览和下载功能》这篇文章主要为大家详细介绍了如何使用Java实现文件图片的预览和下载功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... Java实现文件(图片)的预览和下载 @ApiOperation("访问文件") @GetMapping("

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis