你不知道的5个JVM命令行标志
本文是Neward & Associates的总裁Ted Neward为developerworks独家撰稿“你不知道5个……”系列的一篇文章:JVM有数百个命令行选项,在本文中,您将学习如何监控和记录编译器性能、禁用显式垃圾收集(System.gc();)、扩展 JRE 等等。
本文是Neward & Associates的总裁Ted Neward为developerworks独家撰稿“你不知道5个……”系列中的一篇,JVM是多数开发人员视为理所当然的Java功能和性能背后的重负荷机器。然而,我们很少有人能理解JVM是如何进行工作的—像任务分配和垃圾收集、转动线程、打开和关闭文件、中断和/或JIT编译Java字节码,等等。
不熟悉JVM将不仅会影响应用程序性能,而且当JVM出问题时,尝试修复也会很困难。
本文将介绍一些命令行标志,您可以使用它们来诊断和调优您的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/amods参数将新Integer放在默认的参数前面。
4.verbose
对于虚拟的或任何类型的Java应用程序,-verbose是一个很有用的一级诊断使用程序。该标志有三个子标志:gc、class和jni。
开发人员尝试寻找是否 JVM 垃圾收集器发生故障或者导致性能低下,通常首先要做的就是执行 gc。不幸的是,解释 gc 输出很麻烦 — 足够写一本书。更糟糕的是,在命令行中打印的输出在不同的 Java 版本中或者不在不同的 JVM 中会发生改变,这使得正确解释变得更难。
一般来说,如果垃圾收集器是一个分代收集器(多数“企业级”VMs都是)。某种虚拟标志将会出现,来指出一个全部清扫GC通路;在Sun JVM中,标志在GC输出行的开始以“[FullGC...]”形式出现。
想要诊断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垃圾收集器的标志,没有一个非标准命令行标记是专用于生产使用的。但是,作为工具来刺探在其他方面完全不透明的虚拟机的内部工作,是非常有用的。
关于作者

Ted Neward是Neward & Associates的主管,负责有关Java、.NET、XML服务和其他平台的咨询、指导、培训和推介他现在居住在华盛顿州西雅图附近。
你不知道的5个JVM命令行标志的更多相关文章
- JVM命令行工具&垃圾收集器&垃圾收集策略思维导图
1.JVM命令行工具 2.垃圾回收算法 3.垃圾收集器
- JVM命令行参数解析
1. java命令行参数 先看java命令行的参数 solr@2f1fe8cc9f09:/opt/solr/server/solr-webapp/webapp$ java Usage: java [- ...
- JVM命令行参数
root@ubuntu-blade2:/sdf/jdk# javaUsage: java [-options] class [args...] (to execute a class) or java ...
- JVM命令行选项及GC日志
转:http://blog.csdn.net/q291611265/article/details/48028189 一.设置参数 在使用eclipse编译器的时候,可以采用以下的运行方式来设置虚拟机 ...
- JVM性能监控工具(一)-jdk命令行工具
转载:http://blog.csdn.net/top_code/article/details/51456186 当系统出bug需要定位问题的时候,知识.经验是关键基础,数据是依据,工具是运用知识处 ...
- JVM 第五篇:命令行 JVM 故障处理工具
本文内容过于硬核,建议有 Java 相关经验人士阅读. 1. 引言 虽然我们前面介绍了各种图形化 JVM 故障处理工具,但是很多情况下,我们在处理问题的时候并没有图形化的操作环境可以使用,这时候,就需 ...
- 5个jvm命令
本文是Neward & Associates的总裁Ted Neward为developerworks独家撰稿“你不知道5个……”系列中的一篇,JVM是多数开发人员视为理所当然的Java功能和性 ...
- SpringBootCLI 命令行工具
Spring Boot CLI 是用于快速开发 Spring 应用的命令行工具.用来运行 Groovy (与 Java 风格类似)脚本. spring-cli 似乎不是可以各种diy spring-b ...
- 这些JVM命令配置参数你知道吗?
JVM是多数开发人员视为理所当然的Java功能和性能背后的重负荷机器.然而,我们很少有人能理解JVM是如何进行工作的—像任务分配和垃圾收集.转动线程.打开和关闭文件.中断和/或JIT编译Java字节码 ...
- Java之jdk命令行工具详解
JPS---虚拟机进程状况工具 常用的参数: -l 输出Java应用程序的main class的完整包 -q 仅显示pid,不显示其它任何相关信息 -m 输出传递给main方法的参数 -v 输出传递给 ...
随机推荐
- containerd:配置https私有镜像仓库的最新方法
随着containerd应用越来越广泛,我们必须紧跟官网的节奏. 之前配置https私有镜像仓库的方法比较繁琐,并且不易梳理,下边介绍一下目前最新的配置方法. 配置https私有镜像仓库 我假设你现在 ...
- c++学习笔记(三):函数++
函数PLUS 函数默认参数 在c++中,函数的形参列表中的形参是可以有默认值的.调用函数时,如果未传递参数的值(传入参数为空),则会使用默认值,如果指定了值,则会忽略默认值,使用传递的值. 语法:返回 ...
- jstack排查cpu占用高的步骤
通过jstack排查cpu占用高的问题 1.通过top命令找到cpu占用高的应用程序进程 2.通过top -H -p pid查看该应用中占用CPU高的线程. 3.通过printf "%x\n ...
- 搭建ipv6并发代理池
声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 学习目标 ounter(l ...
- DOM – Web Components
前言 Web Components 已经听过很多年了, 但在开发中用纯 DOM 来实现还是比较少见的. 通常我们是配搭 Angular, React, Vue, Lit 来使用. 这篇就来讲讲纯 We ...
- SpringBoot——整合SSM(主要整合MyBatis)
基于SpringBoot整合SSM SpringBoot整合Spring(不存在) SpringBoot整合SpringMVC(不存在) SpringBoot整合MyBatis(主要) Spring整 ...
- Springboot 项目配置 HTTPS
生成证书 输入命令 keytool -genkeypair -alias "boot" -keyalg "RSA" -keystore "boot.k ...
- 使用ValueConverters扩展实现枚举控制页面的显示
1.ValueConverters 本库包含了IValueConverter接口的的最常用的实现,ValueConverters用于从视图到视图模型的值得转换,某些情况下,可用进行反向转换.里面有一些 ...
- /proc/zoneinfo
root@pita2_mr813_tina35:/# cat /proc/zoneinfo Node 0, zone DMA per-node stats nr_inactive_anon 4749 ...
- Java日期时间API系列17-----Jdk8中java.time包中的新的日期时间API类,java日期计算4,2个日期对比,获取相差年月日部分属性和相差总的天时分秒毫秒纳秒等
通过Java日期时间API系列9-----Jdk8中java.time包中的新的日期时间API类的Period和Duration的区别 ,可以看出java8设计非常好,新增了Period和Durati ...