JVM Parameters

Introduction

HotSpot JVM提供了三类参数:

  • 第一类包括了标准参数。顾名思义,标准参数中包括功能和输出的参数都是很稳定的,很可能在将来的JVM版本中不会改变。你可以用java命令(或者是用java -help)检索出所有标准参数。例如,-server。
  • 第二类是X参数,非标准化的参数在将来的版本中可能会改变。所有的这类参数都以-X开始,并且可以用java -X来检索。注意,不能保证所有参数都可以被检索出来,其中就没有-Xcomp。
  • 第三类是包含XX参数(到目前为止最多的),它们同样不是标准的。然而,在实际情况中X参数和XX参数并没有什么不同。X参数的功能是十分稳定的,然而很多XX参数仍在实验当中(主要是JVM的开发者用于debugging和调优JVM自身的实现)。

    对于布尔类型的参数,有”+”或”-“,然后才设置JVM选项的实际名称。例如,-XX:+用于激活选项,而-XX:-用于注销选项。
    对于需要非布尔值的参数,如String或者Integer,我们先写参数的名称,后面加上”=”,最后赋值。例如,-XX:=赋值
    documentation: https://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

Running Environment

  • Properties
  • Environment Variable

Environment Variable

1
2
3
#!/bin/bash
export MediaMode="PROD"
java -jar boot.jar

Log File

  • -XX:+PrintGC:
  • -XX:+PrintGCDetails:
  • -XX:+PrintGCTimeStamps:

    注意:-XX:+PrintGCTimeStamps该选项打印的是JVM以启动时间为基准的相对时间,对于troubleshooting来说非常困难。使用PrintGCDateStamps代替PrintGCTimeStamps,打印出来的就是真实的日期了。

  • -XX:+PrintGCDateStamps:
  • -XX:+PrintGCApplicationStoppedTime:
  • -XX:+PrintHeapAtGC:
  • -Xloggc:filename:
  • -XX:+PrintAdaptiveSizePolicy:开启该标志后,一旦发生垃圾回收,GC 的日志中会包含垃圾回收时不同的代进行空间调整的细节信息。

Memory

  • -Xms:初始堆大小,默认值为物理内存的1/64。大小通常被视为堆内存大小的下界。

    -XX:InitialHeapSize

  • -Xmx:最大堆大小,默认值为物理内存的1/4

    -XX:MaxHeapSize

  • -Xmn:年轻代大小,例如2g。

  • -XX:MaxDirectMemorySize:堆外内存大小

  • -XX:+HeapDumpOnOutOfMemoryError:让JVM在发生内存溢出时自动的生成堆内存快照。

    默认情况下,堆内存快照会保存在JVM的启动目录下名为java_pid.hprof的文件里(是JVM进程的进程号)。可以通过设置-XX:HeapDumpPath=来改变默认的堆内存快照生成路径,可以是相对或者绝对路径。
    堆内存快照文件有可能很庞大,特别是当内存溢出错误发生的时候。因此,推荐将堆内存快照生成路径指定到一个拥有足够磁盘空间的地方。

  • XX:OnOutOfMemoryError:当内存溢发生时,可以执行一些指令。

    当内存溢出错误发生的时候,我们会将堆内存快照写到/tmp/heapdump.hprof 文件并且在JVM的运行目录执行脚本cleanup.sh
    java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof -XX:OnOutOfMemoryError =”sh ~/cleanup.sh” MyApp

  • -XX:NewSize:指定新生代大小,例如-XX:Newsize=1024m。

  • -XX:MaxNewSize:设置该参数时,应该考虑到新生代只是整个堆的一部分,新生代设置的越大,老年代区域就会减少。一般不允许新生代比老年代还大,因为要考虑GC时最坏情况,所有对象都晋升到老年代。最大可以设置为-Xmx/2。
  • -XX:NewRatio:设置新生代和老年代的相对大小。这种方式的优点是新生代大小会随着整个堆大小动态扩展。

    例如-XX:NewRatio=3指定老年代/新生代为3/1,老年代占堆大小的3/4,新生代占1/4。

  • -XX:SurvivorRatio:指定Eden与survivor大小比例。

    例如-XX:SurvivorRatio=10,表示伊Eden是To/From survivor大小的10倍。所以Eden占新生代大小的10/12,To survivor和From survivor各占新生代的1/12。

  • -XX:PermSize

  • -XX:MaxPermSize

    请注意,PermSize和MaxPermSize设置的永久代大小并不会被包括在使用参数-XX:MaxHeapSize设置的堆内存大小中。
    The JDK 8 HotSpot JVM is now using native memory for the representation of class metadata and is called Metaspace.
    The permanent generation has been removed. The PermSize and MaxPermSize are ignored and a warning is issued if they are present on the command line.
    Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize/MaxPermSize; support was removed in 8.0
    Example: -Xmx512m -XX:MaxPermSize=128m -> -Xmx512m

  • -XX:MetaspaceSize:

  • -XX:MaxMetaspaceSize:

  • -XX:InitialCodeCacheSize

  • -XX:ReservedCodeCacheSize

    JVM一个有趣的,但往往被忽视的内存区域是“代码缓存”,它是用来存储已编译方法生成的本地代码。代码缓存确实很少引起性能问题,但是一旦发生其影响可能是毁灭性的。如果代码缓存被占满,JVM会打印出一条警告消息,并切换到interpreted-only 模式:JIT编译器被停用,字节码将不再会被编译成机器码。因此,应用程序将继续运行,但运行速度会降低一个数量级,直到有人注意到这个问题。

  • -XX:+UseCodeCacheFlushing:当代码缓存被填满时让JVM放弃一些编译代码。

  • Xss:设置单个线程栈的大小

  • GuaranteedSafepointInterval:


Collector

  • -XX:+UseParallelGC:
  • -XX:ParallelGCThreads:
  • -XX:MaxGCPauseMillis:
  • -XX:+UseAdaptiveSizePolicy:
  • -XX:GCTimeRatio:设置垃圾回收时间占程序运行时间的百分比,公式:1/(1+n)
  • -XX:+ScavengeBeforeFullGC:Full GC前调用YGC,默认为true
  • -XX:+MaxTenuringThreshold:Sets the maximum tenuring threshold for use in adaptive GC sizing.

    Parallel Scavenge中默认值为15,CMS中默认值为6,G1中默认值为15。
    为什么最大为15?因为对象头信息里面只分配了4bit来保存对象的age信息。
    这个仅仅表示最大值,因为对象的晋升还与当时Survivor内存大小和存活对象有关,有可能有些对象不需要达到这个阈值就已经晋升到old。


CMS

  • -XX:+UseConcMarkSweepGC:激活CMS收集器,默认HotSpot JVM使用的是并行收集器。
  • -XX:+UseParNewGC:当使用CMS收集器时,该标志激活年轻代使用多线程并行执行垃圾回收。

    对于CMS收集器,年轻代GC算法和老年代GC算法是不同的,因此年轻代GC有两种不同的实现,并且是两个不同的标志。
    注意最新的JVM版本,当使用-XX:+UseConcMarkSweepGC时,-XX:UseParNewGC会自动开启。因此,如果年轻代的并行GC不想开启,可以通过设置-XX:-UseParNewGC来关掉。

  • -XX:+CMSConcurrentMTEnabled:当该标志被启用时,并发的CMS阶段将以多线程执行(因此,多个GC线程会与所有的应用程序线程并行工作)。

  • -XX:+CMSIncrementalMode:该标志将开启CMS收集器的增量模式。

    增量模式经常暂停CMS过程,以便对应用程序线程作出完全的让步。因此,收集器将花更长的时间完成整个收集周期。因此,只有通过测试后发现正常CMS周期对应用程序线程干扰太大时,才应该使用增量模式。由于现代服务器有足够的处理器来适应并发的垃圾收集,所以这种情况发生得很少。

  • -XX:ConcGCThreads:定义并发CMS过程运行时的线程数。比如value=4意味着CMS周期的所有阶段都以4个线程来执行。

    尽管更多的线程会加快并发CMS过程,但其也会带来额外的同步开销。因此,对于特定的应用程序,应该通过测试来判断增加CMS线程数是否真的能够带来性能的提升。
    如果没有设置该标记,JVM会根据并行收集器中的-XX:ParallelGCThreads参数的值来计算出默认的并行CMS线程数。该公式是ConcGCThreads = (ParallelGCThreads + 3)/4。
    因此,对于CMS收集器,-XX:ParallelGCThreads标志不仅影响“stop-the-world”垃圾收集阶段,还影响并发阶段。

  • -XX:+ExplicitGCInvokesConcurrent:前提使用CMS收集器,命令JVM无论什么时候调用系统GC都执行CMS GC,而不是Full GC。

  • -XX:+DisableExplicitGC:禁止代码显式调用System.gc()。
  • -XX:+CMSClassUnloadingEnabled:CMS收集器默认不会对永久代进行垃圾回收。如果希望对永久代进行垃圾回收,可设置该标志。
  • -XX:CMSFullGCsBeforeCompaction:多少次后进行内存压缩
  • -XX:+CMSParallelRemarkEnabled:降低标记停顿
  • -XX+UseCMSCompactAtFullCollection:在FULL GC的时候,对年老代的压缩
  • -XX:CMSInitiatingOccupancyFraction=70:使用CMS作为垃圾回收,当使用70%后开始CMS收集
  • -XX:+PrintOptoAssembly:由编译器线程生成的本地代码被输出并写到“hotspot.log”文件中。使用这个参数要求运行的服务端VM是debug版本。我们可以研究-XX:+PrintOptoAssembly的输出,以至于了解JVM实际执行什么样的优化。

G1

  • -XX:+UseG1GC
  • -XX:MaxGCPauseMillis: Sets a target for the maximum GC pause time.
  • -XX:InitiatingHeapOccupancyPercent: Percentage of the (entire) heap occupancy to start a concurrent GC cycle. GCs that trigger a concurrent GC cycle based on the occupancy of the entire heap and not just one of the generations, including G1, use this option. A value of 0 denotes ‘do constant GC cycles’. The default value is 45.
  • -XX:+UseStringDeduplication
  • -XX:ParallelGCThreads: Number of threads concurrent garbage collectors will use. 设置 STW 工作线程数的值。将 n 的值设置为逻辑处理器的数量。n 的值与逻辑处理器的数量相同,最多为 8。如果逻辑处理器不止八个,则将 n 的值设置为逻辑处理器数的 5/8 左右。这适用于大多数情况,除非是较大的 SPARC 系统,其中 n 的值可以是逻辑处理器数的 5/16 左右。
  • -XX:ConcGCThreads: Sets the number of threads used during parallel phases of the garbage collectors.设置并行标记的线程数。将 n 设置为并行垃圾回收线程数 (ParallelGCThreads) 的 1/4 左右。

https://www.oracle.com/technetwork/cn/articles/java/g1gc-1984535-zhs.html
https://dzone.com/articles/easy-change-to-reduce-memory-by-20


JIT

  • -XX:+PrintCompilation
  • -XX:+CITime
  • -XX:+LogCompilation
  • -XX:+PrintOptoAssembly

Usage

1
java -server -XX:+PrintCompilation hello.jar
1
2
3
4
5
6
7
8
57    1       3       java.lang.String::hashCode (55 bytes)
58 2 3 java.lang.String::length (6 bytes)
58 3 3 java.lang.String::charAt (29 bytes)
59 4 3 java.lang.String::equals (81 bytes)
59 6 3 java.lang.String::indexOf (70 bytes)
59 5 3 java.lang.Object::<init> (1 bytes)
59 7 n 0 java.lang.System::arraycopy (native) (static)
.....

Reference

Java HotSpot VM Options: https://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html
JVM实用参数(七)CMS收集器: http://ifeve.com/useful-jvm-flags-part-7-cms-collector/
JVM实用参数(四)内存调优: http://ifeve.com/useful-jvm-flags-part-4-heap-tuning/
http://www.10tiao.com/html/677/201708/2650887093/1.html
http://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html