MixedGC:
不是 FullGC, 老年代的堆占有率达到参数 (-XX:InitiatingHeapOccupancyPercen) 设定的值则触发, 回收所有的 Young 和部分 Old(根据期望的 GC 停顿时间确定 old 区垃圾收集的优先顺序)以及大对象区, 正常情况 G1 的垃圾收集是先做 MixedGC, 主要使用复制算法, 需要把各个 region 中 存活的对象拷贝到别的 region 里去, 拷贝过程中如果发现没有足够的空 region 能够承载拷贝对象 就会触发一次 Full GC
Full GC:
停止系统程序, 然后采用单线程进行标记, 清理和压缩整理, 好空闲出来一批 Region 来供下一次 MixedGC 使用, 这个过程是非常耗时的.
JVM 参数配置以及优化(JDK1.8)
栈相关
-Xss->设置单个线程栈大小, 比如 - Xss512K, 数值越小, 一个线程栈里能分配的栈帧就越少, 说明可以开启的线程数越多
方法区(元空间)
-XX:MetaspaceSize->设置方法区的大小, 也是触发 GC 的阈值, 比如 - XX:MetaspaceSize=256M
-XX:MaxMetaspaceSiz->设置方法区的最大值, 比如 - XX:MaxMetaspaceSize=256M
堆相关
-Xms->jvm 启动时分配的内存, 比如 - Xms200m
-Xmx->jvm 运行过程中分配的最大内存, 比如 - Xmx500m
-Xmn->设置年轻代大小, 比如 - Xmn2g
-XX:NewSize->设置年轻代大小 比如 - XX:NewSize=2g
-XX:PretenureSizeThreshold->可以设置大对象的大小, 比如 - XX:PretenureSizeThreshold=100000000 单位为 btye.
-XX:MaxTenuringThreshold->设置分代年龄, 比如 - XX:MaxTenuringThreshold=10 默认为 15.
-XX:-HandlePromotionFailure->老年代分配担保机制参数, 1.8 默认开启.
-XX:-UseAdaptiveSizePolicy->禁止 JVM 自动优化 eden 和 Survivor 默认比例 8:1:1, 反之 JVM 默认有这个参数 - XX:+UseAdaptiveSizePolicy, 会导致这个比例自动变化.
-XX:SurvivorRatio->设置 Eden 和 Survivor 大小比如 -XX:SurvivorRatio =8, 注意 Survivor 区有两个. 表示 Eden:Survivor=8:2, 一个 Survivor 区占整个年轻代的 1/10.
-XX:NewRatio->设置老年代和年轻代的比值大小 比如 - XX:NewRatio=4, 表示年老代和年轻代比值为 4:1.
回收器相关
Serial 收集器
-XX:+UseSerialGC->指定年轻代为 Serial 收集器
-XX:+UseSerialOldGC->指定老年代为 Serial 收集器
ParNew 收集器
-XX:+UseParNewG->指定年轻代为 ParNew 收集器
Parallel Scavenge 收集器
-XX:+UseParallelGC->指定年轻代为 Parallel 收集器
-XX:+UseParallelOldGC->指定老年代为 Parallel 收集器
-XX:ParallelGCThreads->指定 GC 工作的线程数量
CMS 收集器
-XX:+UseConcMarkSweepGC->指定指定老年代为 CMS 收集器
-XX:ConcGCThreads->并发的 GC 线程数
-XX:+UseCMSCompactAtFullCollection->FullGC 之后是否做压缩整理(减少碎片)
-XX:CMSFullGCsBeforeCompaction->多少次 FullGC 之后压缩一次, 默认是 0, 代表每次 FullGC 后都会压缩一次, 比如 - XX:CMSFullGCsBeforeCompaction=0
-XX:CMSInitiatingOccupancyFraction->当老年代使用达到该比例时会触发 FullGC(默认是 92, 这是百分比), 比如 - XX:CMSInitiatingOccupancyFaction=92
-XX:+UseCMSInitiatingOccupancyOnly->只使用设定的回收阈值(-XX:CMSInitiatingOccupancyFraction 设定的值), 如果不指定, JVM 仅在第一次使用设定值, 后续则会自动调整
-XX:+CMSScavengeBeforeRemark->在 CMSGC 前启动一次 minor gc, 目的在于减少老年代对年轻代的引用, 降低 CMS GC 的标记阶段时的开销, 一般 CMS 的 GC 耗时 80% 都在 remark 阶段
G1 收集器
-XX:+UseG1GC->开启 G1 收集器
-XX:G1HeapRegionSize->指定分区大小(1MB~32MB, 且必须是 2 的幂), 默认将整堆划分为 2048 个分区
-XX:MaxGCPauseMillis->目标暂停时间(默认 200ms)
-XX:G1NewSizePercent->新生代内存初始空间(默认整堆 5%)
-XX:G1MaxNewSizePercent->新生代内存最大空间
-XX:TargetSurvivorRatio->Survivor 区的填充容量 (默认 50%),Survivor 区域里的一批对象(年龄 1 + 年龄 2 + 年龄 n 的多个年龄对象) 总和超过了 Survivor 区域的 50%, 此时就会把年龄 n(含)以上的对象都放入老年代
-XX:InitiatingHeapOccupancyPercent->老年代占用空间达到整堆内存阈值(默认 45%), 则执行 新生代和老年代的混合收集(MixedGC), 比如我们之前说的堆默认有 2048 个 region, 如果有接近 1000 个 region 都是老年代的 region, 则可能就要触发 MixedGC 了
-XX:G1HeapWastePercent->默认 5%,gc 过程中空出来的 region 是否充足阈值, 在混合回收的时候, 对 Region 回收都是基于复制算法进行的, 都是把要回收的 Region 里的存活对象放入其他 Region, 然后这个 Region 中的垃圾对象全部清理掉, 这样的话在回收过程就会不断空出来新的 Region, 一旦空闲出来的 Region 数量达到了堆内存的 5%, 此时就会立即停止混合回收, 意味着 本次混合回收就结束了.
-XX:G1MixedGCLiveThresholdPercent->默认 85%,region 中的存活对象低于这个值时才会回收该 region, 如果超过这个值, 存活对象过多, 回收的的意义不大.
-XX:G1MixedGCCountTarget->在一次回收过程中指定做几次筛选回收(默认 8 次), 在最后一个筛选回收阶段可以回收一会, 然后暂停回收, 恢复系统运行, 一会再开始回收, 这样可以让系统不至于单次停顿时间过长.
日志调优相关
-XX:+PrintGCDetails->打印 GC 日志
-XX:+PrintGCTimeStamps->打印 GC 时间
-XX:+PrintGCDateStamps->打印 GC 日期
-Xloggc->将 GC 日志保存为文件, 比如 - Xloggc:./gc.log
有兴趣的小伙伴可以自学一下 jmap -heap PID,jstat -gc PID(个人认为这个超级重要),javap -c ***.class,Jstack 等调优命令, 线上尽力别用 jvisualvm 命令, 消耗性能, 很多公司禁用 jvisualvm 命令
我们来回顾一下我们 JVM 都说了什么知识点.
一, 类加载过程: 加载 - 验证 - 准备 - 解析 - 初始化 - 使用 - 卸载
二, 双亲委派机制.
三, 内存运行模型(堆和栈)
四, 内存分区老年代和年轻代, 年轻代包含 Eden 区和 Survivor 区.
五, GC 回收 minor 和 fullGC, 什么时候会触发 fullGC, 重点是对象动态年龄判断和老年代担保分配机制.
六, 垃圾回收的算法, 三种, 复制, 标记清理, 标记整理.
七, 垃圾回收器五种, 串行的 Serial, 并行的 parNew, 高 CPU 的 Parallel, 常用的 CMS 和大内存的 G1.
八, 常用命令.
很多都是孰能生巧的, 细节的还有很多, JVM 优化路我给你们指出了, 剩下的还需要你们自己去探索, 加油~!!!
再不会调优的可以来私信我, 我可以尝试为你提出免费调试建议.
来源: https://www.cnblogs.com/cxiaocai/p/11570519.html