[转]你所不知道的五件事情--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实现Excel与HTML互转

《Java实现Excel与HTML互转》Excel是一种电子表格格式,而HTM则是一种用于创建网页的标记语言,虽然两者在用途上存在差异,但有时我们需要将数据从一种格式转换为另一种格式,下面我们就来看看... Excel是一种电子表格格式,广泛用于数据处理和分析,而HTM则是一种用于创建网页的标记语言。虽然两

java图像识别工具类(ImageRecognitionUtils)使用实例详解

《java图像识别工具类(ImageRecognitionUtils)使用实例详解》:本文主要介绍如何在Java中使用OpenCV进行图像识别,包括图像加载、预处理、分类、人脸检测和特征提取等步骤... 目录前言1. 图像识别的背景与作用2. 设计目标3. 项目依赖4. 设计与实现 ImageRecogni

Java中Springboot集成Kafka实现消息发送和接收功能

《Java中Springboot集成Kafka实现消息发送和接收功能》Kafka是一个高吞吐量的分布式发布-订阅消息系统,主要用于处理大规模数据流,它由生产者、消费者、主题、分区和代理等组件构成,Ka... 目录一、Kafka 简介二、Kafka 功能三、POM依赖四、配置文件五、生产者六、消费者一、Kaf

Java访问修饰符public、private、protected及默认访问权限详解

《Java访问修饰符public、private、protected及默认访问权限详解》:本文主要介绍Java访问修饰符public、private、protected及默认访问权限的相关资料,每... 目录前言1. public 访问修饰符特点:示例:适用场景:2. private 访问修饰符特点:示例:

详解Java如何向http/https接口发出请求

《详解Java如何向http/https接口发出请求》这篇文章主要为大家详细介绍了Java如何实现向http/https接口发出请求,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 用Java发送web请求所用到的包都在java.net下,在具体使用时可以用如下代码,你可以把它封装成一

SpringBoot使用Apache Tika检测敏感信息

《SpringBoot使用ApacheTika检测敏感信息》ApacheTika是一个功能强大的内容分析工具,它能够从多种文件格式中提取文本、元数据以及其他结构化信息,下面我们来看看如何使用Ap... 目录Tika 主要特性1. 多格式支持2. 自动文件类型检测3. 文本和元数据提取4. 支持 OCR(光学

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

JAVA系统中Spring Boot应用程序的配置文件application.yml使用详解

《JAVA系统中SpringBoot应用程序的配置文件application.yml使用详解》:本文主要介绍JAVA系统中SpringBoot应用程序的配置文件application.yml的... 目录文件路径文件内容解释1. Server 配置2. Spring 配置3. Logging 配置4. Ma

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

java脚本使用不同版本jdk的说明介绍

《java脚本使用不同版本jdk的说明介绍》本文介绍了在Java中执行JavaScript脚本的几种方式,包括使用ScriptEngine、Nashorn和GraalVM,ScriptEngine适用... 目录Java脚本使用不同版本jdk的说明1.使用ScriptEngine执行javascript2.