`
hpjianhua
  • 浏览: 236726 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类

关于 JVM 命令行标志您不知道的 5 件事

阅读更多
简介: Java™ 虚拟机有数百个命令行选项,被经验丰富的开发人员用来调优 Java 运行时。本文中,您将学习如何监控和记录编译器性能、禁用显式垃圾收集(System.gc();)、扩展 JRE 等等。

JVM 是多数开发人员视为理所当然的 Java 功能和性能背后的重负荷机器。然而,我们很少有人能理解 JVM 是如何进行工作的 — 像任务分配和垃圾收集、转动线程、打开和关闭文件、中断和/或 JIT 编译 Java 字节码,等等。

不熟悉 JVM 将不仅会影响应用程序性能,而且当 JVM 出问题时,尝试修复也会很困难。

本期 5 件事 系列 将介绍一些命令行标志,您可以使用它们来诊断和调优您的 Java 虚拟机性能。

1. DisableExplicitGC

我已记不清有多少次用户要求我就应用程序性能问题提供咨询了,其实只要跨代码快速运行 grep,就会发现清单 1 所示的问题 — 原始 java 性能反模式:


清单 1. System.gc();

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


显式垃圾收集是一个非常糟糕的主意 — 就像将您和一个疯狂的斗牛犬锁在一个电话亭里。尽管调用的语法是依赖实现的,但如果您的 JVM 正在运行一个分代的垃圾回收器(大多数是)System.gc(); 强迫 VM 执行一个堆的 “全部清扫”,虽然有的没有必要。全部清扫比一个常规 GC 操作要昂贵好几个数量级,这只是个简单数学问题。

您可以不把我的话放在心上 — Sun 的工程师为这个特殊的人工错误提供一个 JVM 标志; -XX:+DisableExplicitGC 标志自动将 System.gc() 调用转换成一个空操作,为您提供运行代码的机会,您自己看看 System.gc() 对于整个 JVM 执行有害还是有利。


--------------------------------------------------------------------------------
2. HeapDumpOnOutOfMemoryError

您有没有经历过这样的情况:JVM 不能使用,不断抛出 OutOfMemoryError,而您又不能为自己创建调试器来捕获它或查看出现了什么问题?像这类偶发和/或不确定的问题,通常使开发人员发疯。

买者自负并不是任何 VM 都支持所有命令行标志,Sun/Oracle 的 VM 除外。查明一个标志是否被支持的最好方法是试用它,看它是否正常工作。倘若这些标志在技术上是不支持的,那么,使用它们您要承担全部责任。如果这些标志中的任何一个使您的代码、您的数据、您的服务器或您的一切消失得无影无踪,我、Sun/Oracle 和 IBM® 都将不负责任。为以防万一,建议先在虚拟(非常生产)环境中实验。
在这个时刻您想要的是,在 JVM 消亡之际捕获堆的一个快照 — 正好 -XX:+HeapDumpOnOutOfMemoryError 命令可以完成这一操作。

运行该命令通知 JVM 拍摄一个 “堆转储快照”,并将其保存在一个文件中以便处理,通常使用 jhat 实用工具(我在 上一篇文章 中介绍过)。您可以使用相应的 -XX:HeapDumpPath 标志指定到保存文件的实际路径。(不管文件保存在哪,务必确保文件系统和/或 Java 流程必须要有权限配置,可以在其中写入。)


--------------------------------------------------------------------------------
3. bootclasspath

定期将一个类放入类路径是很有帮助的,这类路径与库存 JRE 附带的类路径或者以某种方式扩展的 JRE 类路径略有不同。(新 Java Crypto API 提供商就是一个例子)。如果您想要扩展 JRE ,那么您定制的实现必须可以使用引导程序 ClassLoader,该引导程序可以加载 rt.jar 中的 java.lang.Object 及其所有相关文件。

尽管您可以 非法打开 rt.jar 并将您的定制实现或新数据包移入其中,但从技术上您就违反了您下载 JDK 时同意的协议了。

相反,使用 JVM 自己的 -Xbootclasspath 选项,以及皮肤 -Xbootclasspath/p 和 -Xbootclasspath/a。

-Xbootclasspath 使您可以设置完整的引导类路径(这通常包括一个对 rt.jar 的引用),以及一些其他 JDK 附带的(不是 rt.jar 的一部分)JAR 文件。-Xbootclasspath/p 将值前置到现有 bootclasspath 中,并将 -Xbootclasspath/a 附加到其中。

例如,如果您修改了库中的 java.lang.Integer,并将修改放在一个子路径 mods 下,那么 -Xbootclasspath/a mods 参数将新 Integer 放在默认的参数前面。


--------------------------------------------------------------------------------
4. verbose

对于虚拟的或任何类型的 Java 应用程序,-verbose 是一个很有用的一级诊断使用程序。该标志有三个子标志:gc、class 和 jni。

开发人员尝试寻找是否 JVM 垃圾收集器发生故障或者导致性能低下,通常首先要做的就是执行 gc。不幸的是,解释 gc 输出很麻烦 — 足够写一本书。更糟糕的是,在命令行中打印的输出在不同的 Java 版本中或者不在不同的 JVM 中会发生改变,这使得正确解释变得更难。

一般来说,如果垃圾收集器是一个分代收集器(多数 “企业级” VMs 都是)。某种虚拟标志将会出现,来指出一个全部清扫 GC 通路;在 Sun JVM 中,标志在 GC 输出行的开始以 “[Full GC ...]” 形式出现。

想要诊断 ClassLoader 和/或不匹配的类冲突,class 可以帮上大忙。它不仅报告类何时加载,还报告类从何处加载,包括到 JAR 的路径(如果来自 JAR)。

jni 很少使用,除了使用 JNI 或本地库时。打开时,它将报告各种 JNI 事件,比如,本地库何时加载,方法何时弹回;再一次强调,在不同 JVM 版本中,输出会发生变化。


--------------------------------------------------------------------------------
5. Command-line -X

我列出了 JVM 中提供的我喜欢的命令行选项,但是还有一些更多的需要您自己发现,运行命令行参数 -X,列出 JVM 提供的所有非标准(但大部分都是安全的)参数 — 例如:

-Xint,在解释模式下运行 JVM(对于测试 JIT 编译器实际上是否对您的代码起作用或者验证是否 JIT 编译器中有一个 bug,这都很有用)。
-Xloggc:,和 -verbose:gc 做同样的事,但是记录一个文件而不输出到命令行窗口。
JVM 命令行选项时常发生变化,因此,定期查看是一个好主意。甚至,您深夜盯着监控器和下午 5 点回家和妻子孩子吃顿晚饭,(或者在 Mass Effect 2 中消灭您的敌人,根据您的喜好),它们都是不一样的。


--------------------------------------------------------------------------------
结束语

在生产环境中,命令行标志不是为永久使用而设计的 — 事实上,除了您终止用来调优 JVM 垃圾收集器的标志,没有一个非标准命令行标记是专用于生产使用的。但是,作为工具来刺探在其他方面完全不透明的虚拟机的内部工作,是非常有用的。

转载自:http://www.ibm.com/developerworks/cn/java/j-5things11/
分享到:
评论

相关推荐

    你必须知道的5个JVM命令行标志

    你必须知道的5个JVM命令行标志 解压密码 www.jiangyea.com

    关于_JVM_命令行标志您不知道的_5_件事及命令行参数列表

    DisableExplicitGC HeapDumpOnOutOfMemoryError bootclasspath verbose Command-line-X

    5个JVM命令行标志.docx

    java 性能优化,5条JVM命令

    Java程序员必须知道的5个JVM命令行标志

    主要介绍了每个Java程序员必须知道的5个JVM命令行标志,需要的朋友可以参考下

    bcdiff:命令行 JVM 字节码差异工具

    差异bcdiff 是一个用 Scala 编写的命令行 JVM 类文件差异工具。 bcdiff 支持: 显示两个类文件(名称、标志、实现的接口...)之间元数据的差异, 在两个类文件之间以一种聪明的标签感知方式区分匹配方法(具有相同...

    jvm-monitoring-agent:从内部监视JVM,检测线程块并自动保存线程转储

    JVM监控代理 监视JVM线程并在给定时间内阻塞线程时保存线程转储。 用法 从下载jar 将其添加到要监视的应用程序的命令行中: java -javaagent:jvm-monitoring-agent-0.9.0.jar=threshold=1000,debug ...rest of ...

    深入理解_Java_虚拟机 JVM_高级特性与最佳实践

    前 言 致 谢 第一部分 走近Java 第1章 走近Java / 2 1.1 概述 / 2 1.2 Java技术体系 / 3 1.3 Java发展史 / 5 1.4 展望Java技术的未来 / 9 1.4.1 模块化 / 9 1.4.2 混合语言 / 9 1.4.3 多核并行 / 11 ...

    自己动手写Java虚拟机 张秀宏 著

    高清非扫描版 带目录 SBN:978-7-111-53413-6 ...3.2.5 类访问标志 3.2.6 类和超类索引 3.2.7 接口索引表 3.2.8 字段和方法表 3.3 解析常量池 3.3.1 ConstantPool结构体 3.3.2 ConstantInfo接口

    java7集合源码解析-java-xx-options:许多-XXJavaJVM选项的描述

    打印命令行标志 打印出现在命令行上的标志 错误的 布尔值 使用GCLogFileRotation 防止长时间运行的应用程序使用大型 gclog 文件。 需要 -Xloggc:。 从 Java7. 错误的 布尔值 GC 日志文件数 轮换的 gclog 文件数。 ...

    Space-Trader:太空商人混音

    附加说明:您可能需要附加--illegal-access=permit作为jvm标志(IntelliJ中的VM选项)。 libgdx引擎使用大量内部反射,在Java 8以后的版本中默认情况下禁用该内部反射。 如果您对设置有任何疑问,请发送电子邮件至...

    task-closure-tools:关闭工具任务(编译器,生成器,Deps)

    任务关闭工具Closure Tools任务的核心库包括: 使用功能强大的Google Closure编译编译您的JS代码将您的JS代码库连接到一个文件中,也可以选择对其进行编译计算您的JS文件的依赖关系并生成deps.js应用领域您可以将...

    spring-boot-micro-apps

    该项目展示了如何使用Spring和Spring Boot构建“微型”应用程序-最小的功能单元,具有最少的依赖关系和最快的启动... 您可以使用命令行标志运行较小的应用程序: $ java -jar target/micro-0.0.1-SNAPSHOT.jar --thin

    opentelemetry-java-instrumentation:适用于Java的OpenTelemetry自动仪器和工具库

    •• ••适用于Java的OpenTelemetry ... 使用JVM的-javaagent标志启用检测代理。 java -javaagent:path/to/opentelemetry-javaagent-all.jar \ -jar myapp.jar默认情况下,OpenTelemetry Java代理使用程序,该

    Java虚拟机

    这本书的内容是帮你全面了解java虚拟机,本书第1版两年内印刷近10次,98%以上的评论全部为5星级的好评,是整个Java图书领域公认的经典著作和超级畅销书,繁体版在台湾也十分受欢迎。第2版在第1版的基础上做了很大的...

    net学习笔记及其他代码应用

    6.如果在一个B/S结构的系统中需要传递变量值,但是又不能使用Session、Cookie、Application,您有几种方法进行处理? 答 : this.Server.Transfer 7.请编程遍历页面上所有TextBox控件并给它赋值为string.Empty? ...

Global site tag (gtag.js) - Google Analytics