在代码中前行-每个Java程序员必须知道的5个JVM命令行标志

2017-04-21

JVM是多数开发人员视为理所当然的Java功能和性能背后的重负荷机器。然而,我们之间很少有人能理解JVM是如何进行工作的—像任务


分配和垃圾收集、转动线程、打开和关闭文件、中断等等。


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

1.jpg

下面蓝桥将为你介绍一些命令行标志,您可以使用它们来诊断和调优您的Java虚拟机性能。


1.DisableExplicitGC


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


Java性能反模式:


清单1:


1. System.gc();


显式的垃圾的收集是一个非常糟糕的主意—就像将您和一个疯狂的斗牛犬锁在一个电话亭里。尽管我们调用的语法是通过依赖实现的,


但如果您的JVM正在运行一个分代的垃圾回收器(大多数是)System.gc();强迫JVM去执行一个个堆的“全部清扫”,显然虽然有的完全


没有必要。全部清扫比一个常规GC操作要昂贵好几个数量级。



2.HeapDumpOnOutOfMemoryError


您有没有经历过这样的情况:JVM不能使用,通过不断去抛出OutOfMemoryError,而又不能为自己创建

调试器来捕获它或查看出现了什么问题?像这类偶发和/或不确定的问题,使开发人员经常发疯。并不是任何的JVM都支持所有的命令行


标志,Sun/Oracle的VM除外。查明一个标志是否被支持的最好的

方法就是去试用它,看它是不是在正常工作。倘若这些标志在技术上是不支持的,那么,使用它们你需要承担全部责任。如果这些标志


中的任何一个使代码、数据、服务器或一切消失得无影无踪,都将不负责任。为以防万一,建议先在虚拟(非常生产)环境中实验。



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中消灭您的敌人,根据您的喜好)


,它们都是不一样的。



蓝桥为你准备的命令行今天就到这里,我们还会继续,敬请期待!


上一篇:Java就业-好工作都有哪些明显的标志?蓝桥帮你把把关

下一篇:Java工程师-8点经验之谈,蓝桥面试官教你把算法写好