JVM参数
标准参数
标准参数:不随JDK版本变化而变化的参数
常见:
-version
-help
-server
-cp
非标准参数
非标准参数:随着JDK版本而略有区别。
-X参数
-XX参数
主要用于JVM调优和debug。
分为两种类型:布尔类型、name = value
Boolean类型
格式:-XX:[+-]<name> +或-表示启用或者禁用name属性
比如:-XX:+UseConcMarkSweepGC 表示启用CMS类型的垃圾回收器
-XX:+UseG1GC 表示启用G1类型的垃圾回收器
非Boolean类型
格式:-XX<name>=<value>表示name属性的值是value
比如:-XX:MaxGCPauseMillis=500
其他参数
-Xms1000M = -XX:InitialHeapSize=1000M
-Xmx1000M = -XX:MaxHeapSize=1000M
-Xss100 = -XX:ThreadStackSize=100
默认以KB为单位
- 1Byte(字节)=8bit(位)
- 1KB=1024Byte(字节)
- 1MB=1024KB
- 1GB=1024MB
- 1TB=1024GB
查看参数
java -XX:+PrintFlagsFinal -version > flags.txt :将参数打印输出到flags.txt文件中。
JVM参数修饰符的含义
设置参数的常见方式
常见参数的含义
垃圾收集器
垃圾收集算法是方法论,垃圾收集器是落地实现
垃圾收集器
Serial
Serial收集器是一种单线程收集器,STW
优点:简单高效,拥有很高的单线程收集效率
缺点:收集过程需要暂停所有线程
算法:复制算法
适用范围:新生代
应用:Client模式下的默认新生代收集器
执行过程:
Serial GC
Serial Old
Serial Old收集器是Serial收集器的老年代版本,也是一个单线程收集器,不同的是采用"标记-整理算法",STW。
执行过程:
Serial Old
ParNew
ParNew 可以理解为是Serial的多线程版本,是并行垃圾收集器。STW,默认开启的线程数 = 多核CPU的线程,可以通过参数:-XX:ParallelGCThreads 来控制开启的线程数
优点:在多CPU时,比Serial效率高。
缺点:收集过程暂停所有应用程序线程,单CPU时比Serial效率差。
算法:复制算法
适用范围:新生代
应用:运行在Server模式下的虚拟机中首选的新生代收集器
执行过程:
ParNew注意点: 1. STW: stop the world 表示:应用程序的线程和垃圾收集的线程串行执行。 2. 并行:是指垃圾收集器的线程并行的执行。 3. 并发:垃圾收集器线程和应用程序线程一起跑,或者是一些步骤可以一起跑。
Parallel Scavenge
Parallel Scavenge收集器是一个新生代收集器,它也是使用复制算法的收集器,又是并行的多线程收集 器,看上去和ParNew一样,但是Parallel Scanvenge更关注系统的吞吐量。
具体是通过参数:-XX:MaxGCPauseMillis : 停顿时间 和 -XX:MaxGCTimeRatio 吞吐量大小 来控制。
-XX:MaxGCPauseMillis : 停顿时间, 取值: > 0
-XX:MaxGCTimeRatio: 吞吐量大小, 取值:0 ~100 例如:19 = 1/(19+1) = 5% 吞吐量
-XX:UserApaptiveSizePolicy :是一个boolear值,打开以后自动调整新生代的大小。
吞吐量=运行用户代码的时间/(运行用户代码的时间+垃圾收集时间)
比如虚拟机总共运行了100分钟,垃圾收集时间用了1分钟,吞吐量=(100-1)/100=99%。
若吞吐量越大,意味着垃圾收集的时间越短,则用户代码可以充分利用CPU资源,尽快完成程序 的运算任务。
Parallel Old
Parallel Old收集器是Parallel Scavenge收集器的老年代版本,使用多线程和标记****-****整理算法进行垃圾回
收,也是更加关注系统的吞吐量。
CMS
CMS(Concurrent Mark Sweep)收集器是一种以获取 最短回收停顿时间 为目标的收集器。 采用的是"标记-清除算法",整个过程分为4步。
- 初始标记 CMS initial mark
- 并发标记 CMS concurrent mark
- 重新标记 CMS remark
- 并发清除 CMS concurrent sweep 清除不可达对象回收空间,同时有新垃圾产生,留着下次清理称为 浮动垃圾
由于整个过程中,并发标记和并发清除,收集器线程可以与用户线程一起工作,所以总体上来 说,CMS收集器的内存回收过程是与用户线程一起并发地执行的。
CMS垃圾收集器
- 执行过程:
优点:并发收集、低停顿
缺点:产生大量空间碎片、并发阶段会降低吞吐量,还会并发失败
CMS 存在两种主要的工作模式:
backgroud模式为正常模式执行上述的CMS GC流程
-XX:+CMSParalleInitialMarkEnabled :初始标记是否开启多线程, 1.7 默认单线程; 1.8:默认多线程
forefroud模式为Full GC模式
CMS常见设置的参数:
-XX:CMSInitiatingOccupancyFraction CMS回收阈值,默认值 -1 //取值0-100,按百分比回收
-XX:+UseCMSInitiatingOccupancyOnly 辅助参数,如果不开启上面参数只会使用一次就恢复自动调整。CMS扫描线程默认2s一次,如果1s就达到阈值,这时候需要再等1s垃圾才会回收。
当创建对象太多导致backgroud模式 GC失败,这时候就会切换到forefroud模式同时会启用Serial Old 代替CMS将系统STW,重新进行GC Root 并进行一次Full GC。
forefroud 会进行MSC策略,涉及到的两个参数是:
-XX:+UseCMSCompactAtFullCollection 几次Full GC整理我们内存
-XX:CMSFullGCsBeforeCompaction = 0 表示0次之后整理内存
问题1:场景:新生代执行老年代场景,如何处理?
解决办法:并发预处理:在重新标记之前,对新生代对象进行一次Minor GC,来解决全堆扫描的问题。
对应参数是:
- -XX:CMSScheduleRemarkEdenSizeThreshold 默认:= 2M
- -XX:CMSScheduleRemarkEdenPenetration 默认:= 50%
意思是:Eden区大小从2M开始扫描,内存占比到达50%结束 -- 这个策略也叫做可中止的预处理。这段时间如果触发Minor GC 就会进入重新标记阶段,如果没有触发默认等待5s,进入重新标记阶段。
参数:-XX:CMSMaxAbortablePreclean 默认 = 5s
Young区指向Old区的引用发生变化问题2:针对老年代如何处理 全Old区扫描的问题?
解决办法: 首先会将老年代划分为512K 的块,然后将对象引用关系的变化记录到 Card Table (参考:单次遍历算法),并将对应的块记录为dirty Card,当进入重新标记的时候会重新进行标记并清除Card Table 中的 dirty Card。
Old区内引用对象发生变化处理办法
Card Table作用:1. 记录Old区对象引用的变化;2. 记录Old区对象对新生代的引用。
CMS垃圾收集器的相关参数
相关参数: //开启CMS垃圾收集器 -XX:+UseConcMarkSweepGC //默认开启,与-XX:CMSFullGCsBeforeCompaction配合使用 -XX:+UseCMSCompactAtFullCollection //默认0 几次Full GC后开始整理 -XX:CMSFullGCsBeforeCompaction=0 //辅助CMSInitiatingOccupancyFraction的参数,不然CMSInitiatingOccupancyFraction只会使用一次就恢复自动调整,也就是开启手动调整。 -XX:+UseCMSInitiatingOccupancyOnly //取值0-100,按百分比回收 -XX:CMSInitiatingOccupancyFraction 默认-1 注意:CMS并发GC不是“full GC”。HotSpot VM里对concurrent collection和full collection有明确的区分。所有带有“FullCollection”字样的VM参数都是跟真正的full GC相关,而跟CMS并发GC无关的。
网友评论