Java工程师必须要知道的JVM命令行标志
2023-03-06 09:16:24
这篇文章将主要介绍java程序员必须了解的JVM命令行标志。让您了解JVM是如何工作的:任务分配和垃圾收集,旋转线程,打开和关闭文件,中断和/或JIT编译Java字节码等。但愿通过这些命令行标志,您能够对Java虚拟机进行更好的诊断和优化。
1.数据资源GC。
快速地运行grep,您将发现清单1中显示的问题--原始Java性能反模式:
列表1.System.gc();
/Wejustreleasedabunchofobjects,sotellthestupid//garbagecollectortocollectthemalready!System.gc();
明确的垃圾收集是一个很不好的想法——就像把你和一条疯狂的斗牛狗锁在一个电话亭里。虽然调用的语法依赖于实现,但是如果JVM运行的是分代的垃圾回收器(大部分是)System.gc();迫使VM执行堆的“清理”,而有些则不需要。所有的清除比一个普通的GC操作要花费数个数量级,这只是个简单的数学问题。
请不要忘记我说过的话--Sun的工程师为此人工错误提供了JVM标志;-XX:+DisableExplicitGC标志自动将System.gc()调用转换为空操作,让您有机会去运行System.gc()(),这是在整个JVM执行过程中有害还是有利。
2.HeapDumpOnOfMemoryError。
除了Sun/Oracle之外,没有任何VM支持所有命令行标志。找出支持标志的最佳方式就是尝试一下,看看它是否能正常工作。如果从技术上讲,这些标志不受支持,那么使用它们就完全由你负责。无论这些标记是否让你的代码、你的数据、你的服务器或者你的所有东西都消失了,Sun/Oracle和IBM都不会负责。为了以防万一,我们建议首先在虚拟(生产)环境中进行试验。
此时此刻,您希望在JVM消失时捕获堆的快照--正好-XX:+HeapDumpOnOutOfMemoryError命令就能完成此操作。
执行此命令,通知JVM获取“堆转储快照”,并将其保存到文件中进行处理,通常使用jhat实用程序。你可以用-XX:HeapDumpPath标志来指定保存文件的实际路径。(无论文件保存在哪里,一定要确保文件系统和/或Java过程必须具有可写入的权限配置。)
3.bootclasspath。
规律地把一个类放到类路径中会很有用,这种路径与清单JRE附带的类路径或扩展的JRE类路径稍有不同。若要扩展JRE,则必须使用ClassLoader引导程序ClassLoader,它可以在rt.jar中加载java.lang.Object以及所有相关文件。
虽然可以非法打开rt.jar并将您自定义的实现或者新的包移到它中,但是从技术上讲,您违背了您在下载JDK时同意的协议。
取而代之的是JVM自己的-Xbootclasspath选项,以及-Xbootclasspath/p和-Xbootclasspath/a。
通过Xbootclasspath,您可以建立一个完整的启动类路径(这通常包括一个对rt.jar的引用)和一些其他JDK附带的JAR文件(不属于rt.jar的一部分)。-Xbootclasspath/p为现有的bootclasspath添加了-Xbootclasspath/a。
举例来说,如果修改库中的java.lang.Integer,并在子路径mods下添加修改,那么-Xbootclasspath/amods参数将新Integer置于默认参数之前。
4.verbose。
-verbose是一种非常有用的初级诊断用法,适用于虚拟Java应用程序。这个标记有三个子标记:gc,class和jni。
开发者试图找出JVM垃圾收集器是否出了问题或导致性能下降,通常首先要做的就是执行gc。遗憾的是,你很难解释gc输出——足够写本书了。甚至更糟的是,在命令行上打印的输出可能因Java版本或不同的JVM不同而变化,因此很难进行正确解释。
一般而言,如果垃圾回收器是分代收集器(大多数“企业级”VMs都是)。某些虚拟标志将出现,以指出完全清除GC路径;在SunJVM中,当GC输出行的开始以“[FullGC…]”形式出现。
要诊断ClassLoader和/或类冲突不匹配,class能起到很大作用。不但要报告类何时装入,还要报告类从哪里装入,包括JAR的路径(如果来自JAR)。
jni几乎不用,除非是使用JNI或者本地库。当打开时,它将报告各种JNI事件,例如,什么时候本地库被装载,什么时候弹出该方法,再次强调了不同的JVM版本的输出。
5.通信网。
-Xint,以解释模式运行JVM(用于测试JIT编译器是否实际对您的代码有效,或验证JIT编译器中是否存在bug)。
Xloggc:,与-verbose:gc相同,但只将一个文件记录在命令行窗口中。
JVM命令行选项经常会更改,所以定期检查是个好主意。
实际上,命令行标志并非是用来永久使用的。然而,如果使用命令行标志作为一种工具来研究完全不透明的虚拟机的内部工作,仍然是很有用的。上面的JVM命令行标志是Java程序员必须了解的内容。