JVM 参数分类
HotSpot JVM 提供了三类参数。第一类包括了标准参数。顾名思义,标准参数中包括功能和输出的参数都是很稳定的,很可能在将来的JVM版本中不会改变。你可以用java命令(或者是用 java -help)检索出所有标准参数。我们在第一部分中已经见到过一些标准参数,例如:-server。
第二类是X参数,非标准化的参数在将来的版本中可能会改变。所有的这类参数都以-X开始,并且可以用java -X来检索。注意,不能保证所有参数都可以被检索出来,其中就没有-Xcomp。
第三类是包含XX参数(到目前为止最多的),它们同样不是标准的,甚至很长一段时间内不被列出来(最近,这种情况有改变 ,我们将在本系列的第三部分中讨论它们)。然而,在实际情况中X参数和XX参数并没有什么不同。X参数的功能是十分稳定的,然而很多XX参数仍在实验当中(主要是JVM的开发者用于debugging和调优JVM自身的实现)。值的一读的介绍非标准参数的文档HotSpot JVM documentation,其中明确的指出XX参数不应该在不了解的情况下使用。这是真的,并且我认为这个建议同样适用于X参数(同样一些标准参数也是)。不管类别是什么,在使用参数之前应该先了解它可能产生的影响。
理想的情况下,一个Java程序使用JVM的默认设置也可以运行得很好,所以一般来说,没有必要设置任何JVM参数。然而,由于一些性能问题(很不幸的是,这些问题经常出现),一些相关的JVM参数知识会是我们工作中得好伙伴。
内存参数
X参数(非标准选项)
-Xmn2g:设置年轻代的初始和最大大小(以字节为单位)。 附加字母k表示千字节,m表示兆字节,g表示千兆字节。
年轻代用于创建新的对象, GC的执行频率比其他区域高,如果年轻代的规模太小,那么会有很多minor GC。 如果太大,则只会执行Major GC,失去了年轻代存在的意义。 Oracle建议将年轻代的大小保持在整个堆大小的1/4 ~ 1/2之间。
可以使用-XX:NewSize 和 -XX:MaxNewSize 分别设置年轻代的初始大小和最大大小。
-Xms3550m:设置堆的初始大小(以字节为单位)。该值必须是1024的倍数,大于1 MB。附加字母k表示千字节,m表示兆字节,g表示千兆字节。
如果不设置此选项,堆得初始大小将被设置为老年代和年轻代大小的总和。
-Xmx3550m:指定内存分配池的最大大小(以字节为单位)。 该值必须是1024的倍数并且大于2 MB。 附加字母k表示千字节,m表示兆字节,g表示千兆字节。
默认值是在运行时根据系统配置选择的。 对于服务器部署,-Xms和-Xmx通常设置为相同的值,以避免每次垃圾回收完成后JVM重新分配内存。
效果等同于-XX:MaxHeapSize
-Xss128k: 设置每个线程栈的大小(以字节为单位)。 附加字母k表示KB,m表示MB,g表示GB。 默认值取决于平台:应当根据应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。
效果等同于-XX:ThreadStackSize
不同平台下的默认值:
Linux/ARM (32-bit): 320 KB
Linux/i386 (32-bit): 320 KB
Linux/x64 (64-bit): 1024 KB
OS X (64-bit): 1024 KB
Oracle Solaris/i386 (32-bit): 320 KB
Oracle Solaris/x64 (64-bit): 1024 KB
XX参数(高级运行选项)
-XX:PermSize=256M:设置堆内存持久代初始值为256M。
-XX:MaxPermSize=512M:设置持久代最大值为512M。
永久代在JDK8中被完全的移除了。所以永久代的参数-XX:PermSize和-XX:MaxPermSize也被移除了。
在JDK8中,classe metadata,被存储在叫做Metaspace的native memory。一些新的flags被加入:
-XX:MetaspaceSize,class metadata的初始空间配额,以bytes为单位,达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:如果释放了大量的空间,就适当的降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize(如果设置了的话),适当的提高该值。
-XX:MaxMetaspaceSize,可以为class metadata分配的最大空间。默认是没有限制的。
-XX:MinMetaspaceFreeRatio,在GC之后,最小的Metaspace剩余空间容量的百分比,减少为class metadata分配空间导致的垃圾收集
-XX:MaxMetaspaceFreeRatio,在GC之后,最大的Metaspace剩余空间容量的百分比,减少为class metadata释放空间导致的垃圾收集
默认情况下,class metadata的分配仅受限于可用的native memory总量。可以使用MaxMetaspaceSize来限制可为class metadata分配的最大内存。当class metadata的使用的内存达到MetaspaceSize(32位clientVM默认12Mbytes,32位ServerVM默认是16Mbytes)时就会对死亡的类加载器和类进行垃圾收集。设置MetaspaceSize为一个较高的值可以推迟垃圾收集的发生。
-XX:MaxNewSize=size:年轻代的最大大小。
-XX:NewRatio=4:设置堆内存年轻代(包括Eden和两个Survivor区)与堆内存年老代的比值(除去持久代) 。设置为4,则年轻代所占与年老代所占的比值为1:4。
-XX:SurvivorRatio=4: 设置堆内存年轻代中Eden区与Survivor区大小的比值 。设置为4,则两个Survivor区(JVM堆内存年轻代中默认有2个Survivor区)与一个Eden区的比值为1:1:4。
-XX:MaxTenuringThreshold=7:设置对象在Survivor区经历的最大GC次数。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象在年轻代存活时间,增加对象在年轻代即被回收的概率。最大值为15,parallel收集器默认值为15,CMS收集器默认值为6。
回收器选择
JVM给了三种选择:串行收集器、并行收集器、并发收集器,但是串行收集器只适用于小数据量的情况,所以这里的选择主要针对并行收集器和并发收集器。详情参考JVM 垃圾收集器。
默认情况下,JDK5.0以前都是使用串行收集器,如果想使用其他收集器需要在启动时加入相应参数。JDK5.0以后,JVM会根据当前系统配置进行智能判断。
串行收集器
-XX:+UseSerialGC:设置串行收集器并行收集器(吞吐量优先)
-XX:+UseParallelGC:选择垃圾收集器为并行收集器。此配置仅对年轻代有效。即上述配置下,年轻代使用并发收集,而年老代仍旧使用串行收集。
-XX:ParallelGCThreads=20:配置并行收集器的线程数,即:同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等。
-XX:+UseParallelOldGC:配置年老代垃圾收集方式为并行收集。JDK6.0支持对年老代并行收集。
-XX:MaxGCPauseMillis=100:设置每次年轻代垃圾回收的最长时间(单位毫秒),如果无法满足此时间,JVM会自动调整年轻代大小,以满足此值。
-XX:+UseAdaptiveSizePolicy:设置此选项后,并行收集器会自动选择年轻代区大小和相应的Survivor区比例,以达到目标系统规定的最低响应时间或者收集频率等。此参数建议使用并行收集器时,一直打开。
并发收集器(响应时间优先)
-XX:+UseParNewGC:设置年轻代为并发收集。可与CMS收集同时使用。JDK5.0以上,JVM会根据系统配置自行设置,所以无需再设置此值。CMS, 全称Concurrent Low Pause Collector,是jdk1.4后期版本开始引入的新gc算法,在jdk5和jdk6中得到了进一步改进,它的主要适合场景是对响应时间的重要性需求 大于对吞吐量的要求,能够承受垃圾回收线程和应用线程共享处理器资源,并且应用中存在比较多的长生命周期的对象的应用。CMS是用于对tenured generation的回收,也就是年老代的回收,目标是尽量减少应用的暂停时间,减少FullGC发生的几率,利用和应用程序线程并发的垃圾回收线程来 标记清除年老代。
-XX:+UseConcMarkSweepGC:设置年老代为并发收集。
-XX:CMSFullGCsBeforeCompaction=:由于并发收集器不对内存空间进行压缩、整理,所以运行一段时间以后会产生“碎片”,使得运行效率降低。此参数设置运行次FullGC以后对内存空间进行压缩、整理。
-XX:+UseCMSCompactAtFullCollection:打开对年老代的压缩。可能会影响性能,但是可以消除内存碎片。
-XX:+CMSIncrementalMode:设置为增量收集模式。一般适用于单CPU情况。
-XX:CMSInitiatingOccupancyFraction=70:表示年老代空间到70%时就开始执行CMS,确保年老代有足够的空间接纳来自年轻代的对象。注:如果使用 throughput collector 和 concurrent low pause collector 这两种垃圾收集器,需要适当的挺高内存大小,为多线程做准备。
其它
-XX:+ScavengeBeforeFullGC:新生代GC优先于Full GC执行。
-XX:-DisableExplicitGC:禁止调用System.gc(),但JVM的gc仍然有效。
-XX:+MaxFDLimit:最大化文件描述符的数量限制。
-XX:+UseThreadPriorities:启用本地线程优先级API,即使 java.lang.Thread.setPriority() 生效,反之无效。
-XX:SoftRefLRUPolicyMSPerMB=0:“软引用”的对象在最后一次被访问后能存活0毫秒(默认为1秒)。
-XX:TargetSurvivorRatio=90:允许90%的Survivor空间被占用(默认为50%)。提高对于Survivor的使用率——超过就会尝试垃圾回收。辅助信息
-XX:-CITime:打印消耗在JIT编译的时间
-XX:ErrorFile=./hs_err_pid.log:保存错误日志或者数据到指定文件中
-XX:-ExtendedDTraceProbes:开启solaris特有的dtrace探针
-XX:HeapDumpPath=./java_pid.hprof:指定导出堆信息时的路径或文件名
-XX:-HeapDumpOnOutOfMemoryError:当首次遭遇内存溢出时导出此时堆中相关信息-XX:OnError=";":出现致命ERROR之后运行自定义命令
-XX:OnOutOfMemoryError=";":当首次遭遇内存溢出时执行自定义命令
-XX:-PrintClassHistogram:遇到Ctrl-Break后打印类实例的柱状信息,与jmap -histo功能相同
-XX:-PrintConcurrentLocks:遇到Ctrl-Break后打印并发锁的相关信息,与jstack -l功能相同
-XX:-PrintCommandLineFlags:打印在命令行中出现过的标记
-XX:-PrintCompilation:当一个方法被编译时打印相关信息
-XX:-PrintGC:每次GC时打印相关信息
-XX:-PrintGC Details:每次GC时打印详细信息
-XX:-PrintGCTimeStamps:打印每次GC的时间戳
-XX:-TraceClassLoading:跟踪类的加载信息
-XX:-TraceClassLoadingPreorder:跟踪被引用到的所有类的加载信息
-XX:-TraceClassResolution:跟踪常量池
-XX:-TraceClassUnloading:跟踪类的卸载信息
-XX:-TraceLoaderConstraints:跟踪类加载器约束的相关信息
参考