[转]你所不知道的五件事情--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

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟 开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚 第一站:海量资源,应有尽有 走进“智听

在cscode中通过maven创建java项目

在cscode中创建java项目 可以通过博客完成maven的导入 建立maven项目 使用快捷键 Ctrl + Shift + P 建立一个 Maven 项目 1 Ctrl + Shift + P 打开输入框2 输入 "> java create"3 选择 maven4 选择 No Archetype5 输入 域名6 输入项目名称7 建立一个文件目录存放项目,文件名一般为项目名8 确定