`
sunny.yang
  • 浏览: 31722 次
  • 性别: Icon_minigender_2
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论
阅读更多

 

Java 6 JVM 参数选项大全(中文版)

 

作者: Ken Wu

Email: ken.wug@gmail.com

转载本文档请注明原文链接 http://kenwublog.com/docs/java6-jvm-options-chinese-edition.htm

 

本文 是基于最新的 SUN官方 文档 Java SE 6 Hotspot VM Options   编写的译文。主要介绍JVM 中的非稳态选项及其使用说明。

为了让读者明白每个选项的含义,作者在原文基础上补充了大量的资料 。希望这份文档,对正在研究JVM 参数的朋友有帮助!

 

另外,考虑到本文档是初稿,如有描述错误,敬请指正。

 

非稳态 选项使用说明

-XX:+<option> 启用选项

-XX:-<option> 不启用选项

-XX:<option>=<number> 给选项设置一个数字类型值,可跟单位,例如 32k, 1024m, 2g
-XX:<option>=<string>
给选项设置一个字符串值,例如-XX:HeapDumpPath=./dump.core

 

行为 选项

选项

默认值与限制

描述

-XX:-AllowUserSignalHandlers

限于LinuxSolaris ,默认不启用

允许为java 进程安装信号处理器。


Java
信号处理相关知识,详见 http://kenwublog.com/java-asynchronous-notify-based-on-signal

-XX:-DisableExplicitGC

默认不启用

禁止在运行期显式地调用 System.gc()

 

开启该选项后,GC 的触发时机将由Garbage Collector 全权掌控。
注意:你熟悉的代码里没调用System.gc() ,不代表你依赖的框架工具没在使用。

例如RMI 就在多数用户毫不知情的情况下,显示地调用GC 来防止自身OOM

请仔细权衡禁用带来的影响。

-XX:-RelaxAccessControlCheck

默认不启用

Class 校验器中,放松对访问控制的检查。

 

作用与reflection 里的setAccessible 类似。

-XX:-UseConcMarkSweepGC

默认不启用

启用CMS 低停顿垃圾收集器。

 

资料详见: http://kenwublog.com/docs/CMS_GC.pdf

-XX:-UseParallelGC

-server 时启用

其他情况下,默认不启用

策略为新生代使用并行清除,年老代使用单线程Mark-Sweep-Compact 的垃圾收集器。

-XX:-UseParallelOldGC

默认不启用

策略为老年代和新生代都使用并行清除的垃圾收集器。

-XX:-UseSerialGC

-client 时启用

其他情况下,默认不启用

使用串行垃圾收集器。

-XX:+UseSplitVerifier

java5 默认不启用

java6 默认启用

使用新的Class 类型校验器  


Class 类型校验器有什么特点?
Class 类型校验器,将老的校验步骤拆分成了两步:
1
,类型推断。
2
,类型校验。

新类型校验器通过在javac 编译时嵌入类型信息到bytecode 中,省略了类型推断这一步,从而提升了classloader 的性能。

 

Classload顺序 (供参考)
load ->
  verify   -> prepare -> resove -> init


关联选项:
-XX:+FailOverToOldVerifier

-XX:+FailOverToOldVerifier

Java6 新引入选项,默认启用

如果新的Class 校验器检查失败,则使用老的校验器。

 

为什么会失败?

因为JDK6 最高向下兼容到JDK1.2 ,而JDK1.2class info JDK6info 存在较大的差异,所以新校验器可能会出现校验失败的情况。


关联选项:
-XX:+UseSplitVerifier

-XX:+HandlePromotionFailure      

java5 以前是默认不启用,java6 默认启用

关闭新生代收集担保。


什么是新生代收集 担保
在一次理想化的minor gc中,Eden和First Survivor中
的活跃对象会 被复制到Second Survivor。
然而,Second Survivor 不一定能容纳下所有从EFcopy 过来的活跃对象。

为了确保minor gc 能够顺利完成,GC 需要在年老代中额外保留一块足以容纳所有活跃对象的内存空间。
这个预留操作,就被称之为新生代收集担保(New Generation Guarantee )。如果预留操作无法完成时,仍会触发major gc(full gc)

为什么要关闭新生代收集 担保
因为在年老代中预留的空间大小,是无法精确计算的。

为了确保极端情况的发生,GC参考了最坏情况下的新生代内存占用,即Eden+First Survivor。

这种策略无疑是在浪费年老代内存,从时序角度看,还会提前触发Full GC

为了避免如上情况的发生,JVM 允许开发者手动关闭新生代收集担保。

 

在开启本选项后,minor gc 将不再提供新生代收集担保,而是在出现survior 或年老代不够用时,抛出promotion failed 异常。

-XX:+UseSpinning

java1.4.2 1.5 需要手动启用, java6 默认已启用

启用多线程自旋锁优化。


自旋锁优化原理

大家知道,Java 的多线程安全是基于Lock 机制实现的,而Lock 的性能往往不如人意。
原因是,monitorentermonitorexit 这两个控制多线程同步的bytecode 原语,是JVM 依赖操作系统互斥(mutex) 来实现的。
互斥是一种会导致线程挂起,并在较短的时间内又必须重新调度回原线程的,较为消耗资源的操作。

为了避免进入OS 互斥,Java6 的开发者们提出了自旋锁优化。

 

自旋锁优化的原理是在线程进入OS 互斥前,通过CAS 自旋一定的次数来检测锁的释放。

如果在自旋次数未达到预设值前锁已被释放,则当前线程会立即持有该锁。

 

CAS 检测锁的原理详见: http://kenwublog.com/theory-of-lightweight-locking-upon-cas


关联选项:
-XX:PreBlockSpin=10

-XX:PreBlockSpin=10

-XX:+UseSpinning 必须先启用,对于java6 来说已经默认启用了,这里默认自旋10

控制多线程自旋锁优化的自旋次数。( 什么是自旋锁优化?见 -XX:+UseSpinning 处的描述)


关联选项:
-XX:+UseSpinning

-XX:+ScavengeBeforeFullGC      

默认启用

在Full GC前触发一次Minor GC。

-XX:+UseGCOverheadLimit

默认启用

限制GC 的运行时间。如果GC 耗时过长,就抛OOM

-XX:+ UseTLAB

1.4.2 以前和使用-client 选项时,默认不启用,其余版本默认启用

启用线程本地缓存区(Thread Local )。

-XX:+UseThreadPriorities

默认启用

使用本地线程的优先级。

-XX:+UseAltSigs

限于Solaris ,默认启用

为了防止与其他发送信号的应用程序冲突,允许使用候补信号替代 SIGUSR1SIGUSR2

-XX:+UseBoundThreads

限于Solaris , 默认启用

绑定所有的用户线程到内核线程。
减少线程进入饥饿状态(得不到任何cpu time )的次数。

-XX:+UseLWPSynchronization

限于solaris ,默认启用

使用轻量级进程(内核线程)替换线程同步。

-XX:+MaxFDLimit

限于Solaris ,默认启用

设置java 进程可用文件描述符为操作系统允许的最大值。

-XX:+UseVMInterruptibleIO

限于solaris,默认启用

solaris 中,允许运行时中断线程 。



性能选项

 

选项与默认值

默认值与限制

描述

-XX:+ AggressiveOpts

JDK 5 update 6 后引入,但需要手动启用。

JDK6 默认启用。

启用JVM 开发团队最新的调优成果。例如编译优化,偏向锁,并行年老代收集等。

-XX:CompileThreshold=10000

1000

通过JIT 编译器,将方法编译成机器码的触发阀值,可以理解为调用方法的次数,例如调1000 次,将方法编译为机器码。

-XX: LargePageSizeInBytes =4m

默认4m

amd64 位:2m

设置堆内存的内存页大小。

 

调整内存页的方法和性能提升原理,详见 http://kenwublog.com/tune-large-page-for-jvm-optimization

-XX: MaxHeapFreeRatio =70

70

GC 后,如果发现空闲堆内存占到整个预估上限值的70% ,则收缩预估上限值。

 

什么是预估上限值?

JVM 在启动时,会申请最大值(-Xmx 指定的数值)的地址空间,但其中绝大部分空间不会被立即分配(virtual)

它们会一直保留着,直到运行过程中,JVM 发现实际占用接近已分配上限值时,才从virtual 里再分配掉一部分内存。

这里提到的已分配上限值,也可以叫做预估上限值。


引入预估上限值的好处是,可以有效地控制堆的大小。堆越小,GC 效率越高嘛。

注意:预估上限值的大小一定小于或等于最大值。

-XX:MaxNewSize=size

1.3. 1 Sparc: 32m

1.3.1 x86: 2.5m

新生代占整个堆内存的最大值。

-XX:MaxPermSize=64m

5.0 以后 : 64 bit VMs 会增大预设值的30%

1.4 amd64: 96m

1.3.1 -client: 32m

 

其他默认 64m

Perm (俗称方法区)占整个堆内存的最大值。

-XX:MinHeapFreeRatio=40

40

GC 后,如果发现空闲堆内存占到整个预估上限值的40% ,则增大上限值。

( 什么是预估上限值?见 -XX:MaxHeapFreeRatio 处的描述)

 

关联选项:

-XX:MaxHeapFreeRatio=70

-XX:NewRatio=2

Sparc -client: 8

x86 -server: 8

x86 -client: 12

-client: 4 (1.3)

8 (1.3.1+)

x86: 1 2

 

其他默认 2

新生代和年老代的堆内存占用比例。

例如2 例如2表示新生代占年老代的1/2,占整个堆内存的1/3。

-XX:NewSize=2.125m

5.0 以后 : 64 bit Vms 会增大预设值的30%

x86: 1m

x86, 5.0 以后 : 640k

 

其他默认 2.125m

新生代预估上限的默认值。( 什么是预估上限值?见 -XX:MaxHeapFreeRatio 处的描述)

-XX:ReservedCodeCacheSize =32m      

Solaris 64-bit, amd64, -server x86: 48m

1.5.0_06 之前 , Solaris 64-bit a m d64: 1024m

 

其他默认 32m

设置代码缓存的最大值,编译时用。

-XX:SurvivorRatio=8

Solaris amd64: 6

Sparc in 1.3.1: 25

Solaris platforms 5.0 以前 : 32

 

其他默认 8

Eden Survivor 的占用比例。例如8 表示,一个survivor 区占用 1/8 的Eden内存,即1/10的新生代内存,为什么不是1/9?

因为我们的新生代有2个survivor,即S1和S22。所以survivor总共是占用新生代内存的 2/10,Eden与新生代的占比则为 8/10。

-XX: TargetSurvivorRatio =50

50

实际使用的survivor 空间大小占比。默认是50% ,最高90%

-XX:ThreadStackSize=512

Sparc: 512

Solaris x86: 320 (5.0 以前 256)

Sparc 64 bit: 1024

Linux amd64: 1024 ( 5.0 以前 0 )

 

其他默认 512.

线程堆栈大小

-XX:+UseBiasedLocking

JDK 5 update 6 后引入,但需要手动启用。

JDK6 默认启用。

启用偏向锁。

 

偏向锁原理详见 http://kenwublog.com/theory-of-java-biased-locking

-XX:+UseFastAccessorMethods

默认启用

优化原始类型的getter 方法性能。

-XX:-UseISM

默认启用

启用solarisISM

 

详见 Intimate Shared Memory .

-XX:+UseLargePages

JDK 5 update 5 后引入,但需要手动启用。

JDK6 默认启用。

启用大内存分页。

 

调整内存页的方法和性能提升原理,详见 http://kenwublog.com/tune-large-page-for-jvm-optimization

 

关联选项

-XX:LargePageSizeInBytes=4m

-XX:+UseMPSS

1.4.1 之前: 不启用

其余版本默认启用

启用solarisMPSS ,不能与ISM 同时使用。

-XX:+StringCache

默认启用

启用字符串缓存。

-XX: AllocatePrefetchLines =1

1

与机器码指令预读相关的一个选项,资料比较少,本文档不做解释。有兴趣的朋友请自行阅读官方doc

-XX:AllocatePrefetchStyle=1

1

与机器码指令预读相关的一个选项,资料比较少,本文档不做解释。有兴趣的朋友请自行阅读官方doc



调试选项

 

选项与默认值

默认值与限制

描述

-XX:-CITime

1.4 引入。

默认启用

打印JIT 编译器编译耗时。

-XX:ErrorFile=./hs_err_pid<pid>.log

Java 6 引入。

如果JVM crashed ,将错误日志输出到指定文件路径。

-XX:-ExtendedDTraceProbes

Java6 引入,限于solaris

默认不启用

启用 dtrace 诊断。

-XX:HeapDumpPath=./java_pid<pid>.hprof      

默认是java 进程启动位置,即user.dir

堆内存快照的存储文件路径。

 

什么是堆内存快照?

java 进程因OOMcrashOS 强制终止后,会生成一个hprofHeap PROFling )格式的堆内存快照文件。该文件用于线下调试,诊断,查找问题。

文件名一般为

java_<pid>_<date>_<time>_heapDump.hprof

解析快照文件,可以使用 jhat, eclipse MATgdb 等工具。

-XX:-HeapDumpOnOutOfMemoryError

1.4.2 update12 5.0 update 7 引入。

默认不启用

OOM 时,输出一个dump.core 文件,记录当时的堆内存快照(什么是堆内存快照? -XX:HeapDumpPath 处的描述)。

-XX:OnError="<cmd args>;<cmd args>"

1.4.2 update 9 引入

java 每抛出一个ERROR 时,运行指定命令行指令集。指令集是与OS 环境相关的,在linux 下多数是bash 脚本,windows 下是dos 批处理。

-XX:OnOutOfMemoryError="<cmd args>;
<cmd args>"

1.4.2 update 12 java6 时引入

当第一次发生OOM 时,运行指定命令行指令集。指令集是与OS 环境相关的,在linux 下多数是bash 脚本,windows 下是dos 批处理。

-XX:-PrintClassHistogram

默认不启用

Windows, ctrl-breakLinux 下是执行kill -3 (发送SIGQUIT 信号)时,打印class 柱状图。

 

Jmap histo pid 也实现了相同的功能。

详见 http://java.sun.com/javase/6/docs/technotes/tools/share/jmap.html

-XX:-PrintConcurrentLocks

默认不启用

thread dump 的同时,打印 java.util.concurrent 的锁状态。

 

Jstack l pid 也同样实现了同样的功能。

详见 http://java.sun.com/javase/6/docs/technotes/tools/share/jstack.html

-XX:-PrintCommandLineFlags

5.0 引入,默认不启用

Java 启动时,往stdout 打印当前启用的非稳态jvm options

 

例如:

-XX:+UseConcMarkSweepGC -XX:+HeapDumpOnOutOfMemoryError -XX:+DoEscapeAnalysis

-XX:-PrintCompilation

默认不启用

stdout 打印方法被JIT 编译时的信息。

 

例如:

1       java.lang.String::charAt (33 bytes)

-XX:-PrintGC

默认不启用

开启GC 日志打印。

 

打印格式例如:

[Full GC 131115K->7482K(1015808K), 0.1633180 secs]

 

该选项可通过 com.sun.management.HotSpotDiagnosticMXBean API Jconsole 动态启用。

详见 http://java.sun.com/developer/technicalArticles/J2SE/monitoring/#Heap_Dump

-XX:-PrintGCDetails

1.4.0 引入,默认不启用

打印GC 回收的细节。

 

打印格式例如:

[Full GC (System) [Tenured: 0K->2394K(466048K), 0.0624140 secs] 30822K->2394K(518464K), [Perm : 10443K->10443K(16384K)], 0.0625410 secs] [Times: user=0.05 sys=0.01, real=0.06 secs]

 

该选项可通过 com.sun.management.HotSpotDiagnosticMXBean API Jconsole 动态启用。

详见 http://java.sun.com/developer/technicalArticles/J2SE/monitoring/#Heap_Dump

-XX:-PrintGCTimeStamps

默认不启用

打印GC 停顿耗时。

 

打印格式例如:

2.744 : [Full GC (System) 2.744: [Tenured: 0K->2441K(466048K), 0.0598400 secs] 31754K->2441K(518464K), [Perm : 10717K->10717K(16384K)], 0.0599570 secs] [Times: user=0.06 sys=0.00, real=0.06

secs]

 

该选项可通过 com.sun.management.HotSpotDiagnosticMXBean API Jconsole 动态启用。

详见 http://java.sun.com/developer/technicalArticles/J2SE/monitoring/#Heap_Dump

-XX:-PrintTenuringDistribution

默认不启用

打印对象的存活期限信息。

 

打印格式例如:

[GC
Desired survivor size 4653056 bytes, new threshold 32 (max 32)
- age 1: 2330640 bytes, 2330640 total
- age 2: 9520 bytes, 2340160 total

204009K->21850K(515200K), 0.1563482 secs]

 

Age1 2 表示在第12GC 后存活的对象大小。

-XX:-TraceClassLoading

默认不启用

打印class 装载信息到stdout 。记Loaded 状态。

 

例如:

[Loaded java.lang.Object from /opt/taobao/install/jdk1.6.0_07/jre/lib/rt.jar]

-XX:-TraceClassLoadingPreorder

1.4.2 引入,默认不启用

class 的引用/ 依赖顺序打印类装载信息到stdout 。不同于 TraceClassLoading ,本选项只记 Loading 状态。

 

例如:

[Loading java.lang.Object from /home/confsrv/jdk1.6.0_14/jre/lib/rt.jar]

-XX:-TraceClassResolution

1.4.2 引入,默认不启用

打印所有静态类,常量的代码引用位置。用于debug

 

例如:

RESOLVE java.util.HashMap java.util.HashMap$Entry HashMap.java:209

 

说明HashMap 类的209 行引用了静态类 java.util.HashMap$Entry

-XX:-TraceClassUnloading

默认不启用

打印class 的卸载信息到stdout 。记Unloaded 状态。

-XX:- TraceLoaderConstraints

Java6 引入,默认不启用

打印class 的装载策略变化信息到stdout

 

例如:

[Adding new constraint for name: java/lang/String, loader[0]: sun/misc/Launcher$ExtClassLoader, loader[1]: <bootloader> ]

[Setting class object in existing constraint for name: [Ljava/lang/Object; and loader sun/misc/Launcher$ExtClassLoader ]

[Updating constraint for name org/xml/sax/InputSource, loader <bootloader>, by setting class object ]

[Extending constraint for name java/lang/Object by adding loader[15]: sun/reflect/DelegatingClassLoader  ]

 

装载策略变化是实现classloader 隔离/ 名称空间一致性的关键技术。

对此感兴趣的朋友,详见 http://kenwublog.com/docs/Dynamic+Class+Loading+in+the+Java+Virtual+Machine.pdf 中的 contraint rules 一章。

-XX:+ PerfSaveDataToFile

默认启用

java 进程因OOMcrashed 被强制终止后,生成一个堆快照文件(什么是堆内存快照? -XX:HeapDumpPath 处的描述)。

 

作者敬告

完善的单元测试,功能回归测试,和性能基准测试可以减少因调整非稳态JVM 选项带来的风险。

 

参考资料

Java6 性能调优白皮书

http://java.sun.com/performance/reference/whitepapers/6_performance.html

Java6 GC 调优指南

http://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html

全面的options列表

http://blogs.sun.com/watt/resource/jvm-options-list.html

原文链接:http://kenwublog.com/docs/java6-jvm-options-chinese-edition.htm

 

 

分享到:
评论

相关推荐

    tomcat6.0 修改启动内存设置 java jvm参数配置

    ### Tomcat 6.0 修改启动内存设置及 Java JVM 参数配置详解 #### 一、背景与目的 在部署和运行 Java Web 应用时,合理地配置应用服务器(如 Apache Tomcat)的内存是非常重要的。这不仅可以提升应用程序的性能,还...

    jdk8 jvm 参数图(随手参考好资料)

    常用jvm参数都在这张图中,参考起来方便,是国外大神整理的

    关键业务系统JVM参数推荐

    ### 关键业务系统JVM参数推荐 #### 一、引言 在关键业务系统中,除了追求高吞吐量和低延迟之外,系统的稳定性和问题排查的便捷性同样至关重要。因此,选择合适的JVM参数变得尤为重要。本文将详细介绍一些常用的JVM...

    IBM JVM参数选项

    **: 显示帮助信息,介绍可用的所有JVM参数。 - 示例:`-help` 3. **-fullversion**: 输出JVM的完整版本信息。 - 示例:`-fullversion` 4. **-showversion**: 显示JVM的版本信息。 - 示例:`-showversion` 5. *...

    jvm参数设置

    ### JVM参数设置详解 在Java应用开发与维护过程中,JVM(Java虚拟机)的配置至关重要,它直接影响到应用程序的性能表现与稳定性。本文将基于提供的文件内容,深入解析Linux环境下JVM的基本参数设置方法及原理。 ##...

    设置Eclipse的JVM参数

    ### 设置Eclipse的JVM参数 #### 一、引言 在进行Java开发时,Eclipse作为一款广泛使用的集成开发环境(IDE),其性能优化对于提高开发效率和应用稳定性至关重要。其中,设置合适的JVM(Java虚拟机)参数是优化...

    jvm 配置jvm参数

    ### JVM参数配置详解 #### 一、理解JVM参数配置的重要性 Java Virtual Machine (JVM) 是运行Java程序的核心环境,其性能优化很大程度上依赖于正确的JVM参数配置。合理配置JVM参数不仅可以显著提升应用程序的运行...

    jvm参数与系统性能的优化

    JVM 参数与系统性能的优化 在 Java 虚拟机(JVM)中,参数设置对系统性能的影响是至关重要的。通过设置合适的 JVM 参数,可以提高系统性能,减少垃圾回收的频率和时间,提高应用程序的执行效率。 第一点:设置堆栈...

    jvm 参数及gc详解

    本文将深入探讨JVM参数及其与Java垃圾收集相关的知识。 一、JVM参数详解 JVM参数可以分为三类:启动参数(-X),标准参数(-XX),以及非公开(实验性)参数(-XX:)。这些参数允许开发者对JVM的行为进行精细调整...

    jvm参数设置_JVM参数设置_

    JVM参数设置是优化Java应用性能的关键环节,它可以帮助我们控制JVM的行为,如内存分配、垃圾回收策略、线程调度等。下面将详细介绍一些重要的JVM参数及其作用。 1. 内存设置: - `-Xms` 和 `-Xmx`:这两个参数用于...

    JVM参数优化及JVM解析.docx

    根据JVM参数的设置,堆可以被划分为新生代和老年代,新生代又进一步细分为Eden区和两个Survivor区。5、方法区:也称为永久代,存储类的信息、常量、静态变量等,JDK 8之后被元空间(Metaspace)取代,元空间使用的是...

    JVM优化3(Tomcat参数调优,JVM参数调优,jvm字节码,代码优化).pdf

    本篇文件内容主要介绍了JVM优化的第三部分,重点围绕Tomcat参数调优、JVM参数调优、JVM字节码优化以及代码优化等几个方面。下面是针对这些知识点的详细解释: 1. Tomcat参数调优 在Tomcat参数调优部分,首先介绍了...

    Java 6 JVM 参数选项大全

    特别是在Java、J2EE等大型应用中,通过合理设置JVM参数可以极大提升系统的整体性能与稳定性。 #### JVM 非标准参数的重要性 JVM非标准参数主要指那些用于优化JVM内部行为的配置项,这些参数通常在开发阶段被忽略或...

    简单实用JVM参数配置

    【JVM参数配置详解】 Java Virtual Machine (JVM) 是Java程序的核心组成部分,它负责解析和执行Java程序的字节码。JVM的设计目标是提供跨平台的运行环境,通过在实际硬件上模拟一个虚拟的计算机系统,使得Java程序...

    Linux简单调优与JVM参数.docx

    Linux 服务器调优与 JVM 参数调优 本文主要介绍了 Linux 服务器调优和 JVM 参数调优的相关知识点,以便提高服务器性能和 JVM 应用程序的运行效率。 Linux 服务器调优 Linux 服务器调优是指对 Linux 操作系统的...

    jvm 参数调优实践

    JVM参数调优是优化Java应用程序性能的关键环节,尤其是在服务器端的应用中,如Web服务器Resin。本实践案例中,作者分别尝试了三种不同的垃圾回收(GC)策略:串行回收、并行回收和并发回收,并针对每种策略提供了...

    JVM 参数汇总.pdf

    以下是一些关键的JVM参数及其作用: 1. **Xms** 和 **Xmx**: 这两个参数用于设置Java堆内存的大小。`Xms`设定初始堆大小,而`Xmx`设定最大堆大小。确保`Xms`小于或等于`Xmx`,以避免内存不足错误。通常,它们的值会...

Global site tag (gtag.js) - Google Analytics