zoukankan      html  css  js  c++  java
  • JVM不稳定参数

            -XX 参数被称为不稳定参数,之所以这么叫是因为此类参数的设置很容易引起JVM 性能上的差异,使JVM 存在极大的不稳定性。当然这是在非合理设置的前提下,如果此类参数设置合理讲大大提高JVM 的性能及稳定性。
            可以说“不稳定参数”是一柄双刃剑,用的好攻无不克,用的差讲带来麻烦。如何合理利用不稳定参数一直是一个不断实践不断改善的过程,无法用统一的标准去衡量。一切都需要在系统的不断运行,问题不断出现,参数不断修改,重新不断运行的循环过程中完善。也就是说没有最好的配置标准,只有适合当前系统的标准。这是一个循序渐进的过程。但有一些前人总结过得经验教训可供我们来参考,并去寻找适合自己的那些配置。
            本节着重展示常用的-XX 类型参数列表及作用,不稳定参数的优化会在JVM 优化部分详细讲解。

            不稳定参数语法规则:
            1.布尔类型参数值
            -XX:+<option> '+'表示启用该选项
            -XX:-<option> '-'表示关闭该选项
            2.数字类型参数值:
            -XX:<option>=<number> 给选项设置一个数字类型值,可跟随单位,例如:'m'或'M'表示兆字节;'k'或'K'千字节;'g'或'G'千兆字节。32K与32768是相同大小的。
            3.字符串类型参数值:
            -XX:<option>=<string> 给选项设置一个字符串类型值,通常用于指定一个文件、路径或一系列命令列表。例如:-XX:HeapDumpPath=./dump.core


            下面就是不同类型的参数值及意义。

            行为选项:

    选项 默认值 描述
    -XX:-AllowUserSignalHandlers

    限于Linux和Solaris

    默认关闭

    允许为java进程安装信号处理器。
    -XX:AltStackSize=16384

    仅适用于Solaris

    从5.0中删除

    备用信号堆栈大小(以字节为单位)
    -XX:-DisableExplicitGC 默认关闭 禁止在运行期显式地调用 System.gc()。
     
    开启该选项后,GC的触发时机将由Garbage Collector全权掌控。
    注意:你熟悉的代码里没调用System.gc(),不代表你依赖的框架工具没在使用。
    例如RMI就在多数用户毫不知情的情况下,显示地调用GC来防止自身OOM。
    请仔细权衡禁用带来的影响。
    -XX:+FailOverToOldVerifier

    Java6新引入选项

    默认启用

    如果新的Class校验器检查失败,则使用老的校验器。
     
    为什么会失败?
    因为JDK6最高向下兼容到JDK1.2,而JDK1.2的class info 与JDK6的info存在较大的差异,所以新校验器可能会出现校验失败的情况。

    关联选项:
    -XX:+UseSplitVerifier
    -XX:+HandlePromotionFailure

    Java1.5以前默认关闭

    Java1.6后默认启用

    关闭新生代收集担保。

    什么是新生代收集担保?
    在一次理想化的minor gc中,Eden和First Survivor中的活跃对象会被复制到Second Survivor。
    然而,Second Survivor不一定能容纳下所有从E和F区copy过来的活跃对象。
    为了确保minor gc能够顺利完成,GC需要在年老代中额外保留一块足以容纳所有活跃对象的内存空间。
    这个预留操作,就被称之为新生代收集担保(New Generation Guarantee)。如果预留操作无法完成时,仍会触发major gc(full gc)。

    为什么要关闭新生代收集担保?

    因为在年老代中预留的空间大小,是无法精确计算的。
    为了确保极端情况的发生,GC参考了最坏情况下的新生代内存占用,即Eden+First Survivor。
    这种策略无疑是在浪费年老代内存,从时序角度看,还会提前触发Full GC。
    为了避免如上情况的发生,JVM允许开发者手动关闭新生代收集担保。
     
    在开启本选项后,minor gc将不再提供新生代收集担保,而是在出现survior或年老代不够用时,抛出promotion failed异常。
    -XX:+MaxFDLimit

    限于Solaris

    默认启用

    设置java进程可用文件描述符为操作系统允许的最大值。
    -XX:PreBlockSpin=10 默认值:10 控制多线程自旋锁优化的自旋次数。(什么是自旋锁优化?见 -XX:+UseSpinning 处的描述)

    前置选项:
    -XX:+UseSpinning
    -XX:-RelaxAccessControlCheck

    默认关闭

    Java1.6引入

    在Class校验器中,放松对访问控制的检查。
     
    作用与reflection里的setAccessible类似。
    -XX:+ScavengeBeforeFullGC 默认启用 在Full GC前触发一次Minor GC
    -XX:+UseAltSigs

    限于Solaris

    默认启用

    为了防止与其他发送信号的应用程序冲突,允许使用候补信号替代 SIGUSR1和SIGUSR2。
    -XX:+UseBoundThreads

    限于Solaris

    默认启用

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

    默认关闭

    Java1.4引入

    启用CMS低停顿垃圾收集器。
    -XX:+UseGCOverheadLimit

    默认启用

    Java1.6引入

    限制GC的运行时间。如果GC耗时过长,就抛OutOfMemoryError。
    -XX:+UseLWPSynchronization

    限于solaris

    默认启用

    Java1.4引入

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

    -server时启用

    其他情况下:默认关闭

    Java1.4引入

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

    默认关闭

    Java1.5引入

    为老年代和新生代都使用并行清除的垃圾收集器。开启此选项将自动开启-XX:+UseParallelGC 选项
    -XX:-UseSerialGC

    -client时启用

    默认关闭

    Java1.5引入

    使用串行垃圾收集器。
    -XX:-UseSpinning

    Java1.4.2和1.5需要手动启用,

    Java1.6默认已启用

    启用多线程自旋锁优化。

    自旋锁优化原理
    大家知道,Java的多线程安全是基于Lock机制实现的,而Lock的性能往往不如人意。
    原因是,monitorenter与monitorexit这两个控制多线程同步的bytecode原语,是JVM依赖操作系统互斥(mutex)来实现的。
    互斥是一种会导致线程挂起,并在较短的时间内又必须重新调度回原线程的,较为消耗资源的操作。
    为了避免进入OS互斥,Java6的开发者们提出了自旋锁优化。
     
    自旋锁优化的原理是在线程进入OS互斥前,通过CAS自旋一定的次数来检测锁的释放。
    如果在自旋次数未达到预设值前锁已被释放,则当前线程会立即持有该锁。
     
    关联选项:
    -XX:PreBlockSpin=10
    -XX:+UseTLAB

    Java1.4.2以前和使用-client选项时:默认关闭

    其余版本默认启用

    启用线程本地缓存区(Thread Local)
    -XX:+UseSplitVerifier

    Java1.5默认关闭

    Java1.6默认启用

    使用新的Class类型校验器 。

    新Class类型校验器,将老的校验步骤拆分成了两步:
    1.类型推断。
    2.类型校验。

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

    关联选项:
    -XX:+FailOverToOldVerifier
    -XX:+UseThreadPriorities 默认启用 使用本地线程的优先级。
    -XX:+UseVMInterruptibleIO

    限于solaris

    默认启用

    Java1.6引入

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

            第一垃圾收集器 (G1) 垃圾收集选项:

    选项 默认值 描述
    -XX:+UseG1GC 默认关闭 使用G1垃圾处理器
    -XX:MaxGCPauseMillis=n 默认值:4294967295 设置并行收集最大暂停时间,这是一个理想目标,JVM将尽最大努力来实现它。
    -XX:InitiatingHeapOccupancyPercent=n 默认值:45 启动一个并发垃圾收集周期所需要达到的整堆占用比例。这个比例是指整个堆的占用比例而不是某一个代(例如G1),如果这个值是0则代表‘持续做GC’。默认值是45
    -XX:NewRatio=n 默认值:2 设置年轻代和年老代的比值。例如:值为3,则表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4。
    -XX:SurvivorRatio=n 默认值:8 年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5
    -XX:MaxTenuringThreshold=n 默认值:15 设置垃圾最大存活阀值。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论。
    -XX:ParallelGCThreads=n 默认值:随JVM运行平台不同而异 配置并行收集器的线程数,即:同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等。
    -XX:ConcGCThreads=n 默认值:随JVM运行平台不同而异 Number of threads concurrent garbage collectors will use. The default value varies with the platform on which the JVM is running.
    -XX:G1ReservePercent=n 默认值:10 设置保留用来做假天花板以减少晋升(新生代对象晋升到老生代)失败可能性的堆数目。
    -XX:G1HeapRegionSize=n 默认值根据堆大小而定 使用G1垃圾回收器,java堆被划分成统一大小的区块。这个选项设置每个区块的大小。最小值是1Mb,最大值是32Mb。

            性能选项:

    选项 默认值 描述
    -XX:+AggressiveOpts

    Java1.5 引入

    默认关闭

    Java1.6后默认开启

    开启编译器性能优化。
    -XX:CompileThreshold=10000 默认值:1000 通过JIT编译器,将方法编译成机器码的触发阀值,可以理解为调用方法的次数,例如调1000次,将方法编译为机器码。 [-client: 1,500]
    -XX:LargePageSizeInBytes=4m

    默认值:4m

    amd64位:2m

    设置堆内存的内存最大值。
    -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
    新生代占整个堆内存的最大值。从Java1.4开始, MaxNewSize成为 NewRatio的一个函数
    -XX:MaxPermSize=64m

    Java1.5以后::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: 12 
    其他:2
    新生代和年老代的堆内存占用比例。 例如2例如2表示新生代占年老代的1/2,占整个堆内存的1/3。
    -XX:NewSize=2m

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

    x86: 1m

    x86, 5.0以后: 640k

    其他:2.125m

    新生代预估上限的默认值。
    -XX:ReservedCodeCacheSize=32m Solaris 64-bit, amd64, -server x86: 48m 
    1.5.0_06之前, Solaris 64-bit 
    amd64: 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空间大小占比。默认是47%,最高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

    Java1.5 update 6后引入

    默认关闭。

    Java1.6默认启用。

    启用偏向锁。实例详解
    -XX:+UseFastAccessorMethods 默认启用 优化原始类型的getter方法性能。
    -XX:-UseISM 默认启用 启用solaris的ISM。 Intimate Shared Memory.
    -XX:+UseLargePages

    Java1.5 update 5后引入

    默认关闭

    Java1.6默认启用。

    启用大内存分页。 
    调整内存页的方法和性能提升原理,详见Java Support for Large Memory Pages 
    关联选项:
    -XX:LargePageSizeInBytes=4m
    -XX:+UseMPSS

    Java1.4.1 之前默认关闭

    其他版本默认启用

    启用solaris的MPSS,不能与ISM同时使用。
    -XX:+UseStringCache 默认开启 缓存常用字符串。
    -XX:AllocatePrefetchLines=1 默认值:1 在使用JIT生成的预读取指令分配对象后读取的缓存行数。如果上次分配的对象是一个实例则默认值是1,如果是一个数组则是3
    -XX:AllocatePrefetchStyle=1 默认值:1 预读取指令的生成代码风格
    0- 无预读取指令生成 
    1-在每次分配后执行预读取命令 
    2-当预读取指令执行后使用TLAB()分配水印指针来找回入口
     
    -XX:+UseCompressedStrings Java1.6 update 21引入 其中,对于不需要16位字符的字符串,可以使用byte[] 而非char[]。对于许多应用,这可以节省内存,但速度较慢(5%-10%)
    -XX:+OptimizeStringConcat Java1.6 update 20引入 在可能的情况下优化字符串连接操作。

            调试选项:

    选项 默认值 描述
    -XX:-CITime 默认启用 打印JIT编译器编译耗时。
    -XX:ErrorFile=./hs_err_pid<pid>.log Java1.6引入 如果JVM crashed,将错误日志输出到指定文件路径。
    -XX:-ExtendedDTraceProbes Java6引入,限于solaris,默认关闭 启用dtrace诊断
    -XX:HeapDumpPath=./java_pid<pid>.hprof 默认是java进程启动位置 堆内存快照的存储文件路径。
     
    什么是堆内存快照?
    当java进程因OOM或crash被OS强制终止后,会生成一个hprof(Heap PROFling)格式的堆内存快照文件。该文件用于线下调试,诊断,查找问题。
    文件名一般为
    java_<pid>_<date>_<time>_heapDump.hprof
    解析快照文件,可以使用 jhat, eclipse MAT,gdb等工具。
    -XX:-HeapDumpOnOutOfMemoryError 默认关闭 在java.lang.OutOfMemoryError 异常出现时,输出一个dump.core文件,记录当时的堆内存快照(见 -XX:HeapDumpPath 的描述)。
    -XX:OnError="<cmd args>;<cmd args>" Java1.4引入 当java每抛出一个ERROR时,运行指定命令行指令集。指令集是与OS环境相关的,在Linux下多数是.sh脚本,windows下是.bat批处理。
    -XX:OnOutOfMemoryError="<cmd args>; 
    <cmd args>"
    Java1.4.2 update 12和Java6时引入 当第一次发生java.lang.OutOfMemoryError 时,运行指定命令行指令集。指令集是与OS环境相关的,在linux下多数是.sh脚本,windows下是.bat批处理。
    -XX:-PrintClassHistogram 默认关闭 在Windows下, 按ctrl-break或Linux下是执行kill -3(发送SIGQUIT信号)时,打印class柱状图。 
    jmap -histo pid也实现了相同的功能。
    -XX:-PrintConcurrentLocks 默认关闭 在thread dump的同时,打印java.util.concurrent的锁状态。
    jstack -l pid 也同样实现了同样的功能。
    -XX:-PrintCommandLineFlags Java1.5 引入,默认关闭 Java启动时,往stdout打印当前启用的非稳态jvm options。 
    例如: 
    -XX:+UseConcMarkSweepGC -XX:+HeapDumpOnOutOfMemoryError -XX:+DoEscapeAnalysis
    -XX:-PrintCompilation 默认关闭 往stdout打印方法被JIT编译时的信息。
    -XX:-PrintGC 默认关闭 开启GC日志打印。 
    显示结果例如: 
    [Full GC 131115K->7482K(1015808K), 0.1633180 secs] 
    该选项可通过 com.sun.management.HotSpotDiagnosticMXBean API 和 jconsole 动态启用。
    -XX:-PrintGCDetails Java1.4引入,默认关闭 打印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 动态启用。
    -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 动态启用。
    -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表示在第1和2次GC后存活的对象大小。
    -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 Java1.6 引入,默认关闭 打印class的装载策略变化信息到stdout。
    例如:
    [Adding new constraint for name: java/lang/String, loader[0]: sun/misc/Launcher$ExtClassLoader, loader[1]: ]
    [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 , by setting class object ]
    [Extending constraint for name java/lang/Object by adding loader[15]: sun/reflect/DelegatingClassLoader ]
    装载策略变化是实现classloader隔离/名称空间一致性的关键技术。
    -XX:+PerfSaveDataToFile 默认启用 当java进程因java.lang.OutOfMemoryError 异常或crashed 被强制终止后,生成一个堆快照文件。
    -XX:ParallelGCThreads=n 默认值:随JVM运行平台不同而异 配置并行收集器的线程数,即:同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等。
    -XX:+UseCompressedOops 32位默认关闭,64位默认启动 使用compressed pointers。这个参数默认在64bit的环境下默认启动,但是如果JVM的内存达到32G后,这个参数就会默认为不启动,因为32G内存后,压缩就没有多大必要了,要管理那么大的内存指针也需要很大的宽度了
    -XX:+AlwaysPreTouch 默认关闭 在JVM 初始化时预先对Java堆进行摸底。
    -XX:AllocatePrefetchDistance=n 默认值取决于当前JVM 设置 为对象分配设置预取距离。
    -XX:InlineSmallCode=n 默认值取决于当前JVM 设置 当编译的代码小于指定的值时,内联编译的代码。
    -XX:MaxInlineSize=35 默认值:35 内联方法的最大字节数。
    -XX:FreqInlineSize=n 默认值取决于当前JVM 设置 内联频繁执行的方法的最大字节码大小。
    -XX:LoopUnrollLimit=n 默认值取决于当前JVM 设置 代表节点数目小于给定值时打开循环体。
    -XX:InitialTenuringThreshold=7 默认值:7 设置初始的对象在新生代中最大存活次数。
    -XX:MaxTenuringThreshold=n 默认值:15,最大值:15 设置对象在新生代中最大的存活次数,最大值15,并行回收机制默认为15,CMS默认为4。
    -Xloggc:<filename> 默认关闭 输出GC 详细日志信息至指定文件。
    -XX:-UseGCLogFileRotation 默认关闭 开启GC 日志文件切分功能,前置选项 -Xloggc
    -XX:NumberOfGClogFiles=1 必须>=1,默认值:1 设置切分GC 日志文件数量,文件命名格式:.0, .1, ..., .n-1
    -XX:GCLogFileSize=8K 必须>=8K,默认值:8K GC日志文件切分大小。

            下一节内容将讨论如果优化及合理配置这些JVM 参数。

  • 相关阅读:
    React在componentDidMount里面发送请求
    React 术语词汇表
    React里受控与非受控组件
    React和Vue等框架什么时候操作DOM
    【LeetCode】79. Word Search
    【LeetCode】91. Decode Ways
    【LeetCode】80. Remove Duplicates from Sorted Array II (2 solutions)
    【LeetCode】1. Two Sum
    【LeetCode】141. Linked List Cycle (2 solutions)
    【LeetCode】120. Triangle (3 solutions)
  • 原文地址:https://www.cnblogs.com/vana/p/9732937.html
Copyright © 2011-2022 走看看