第三章:垃圾回收器-老年代收集器

Serial Old收集器
Serial Old收集器时Serial收集器的老年代版本。
同样是单线程收集器。
使用“标记-整理”算法。
默认也是给client模式下使用的老年单收集器。
该收集器可以作为CMS收集器的后备预案;
Parallel Old收集器
Parallel Old是Parallel Scavenger收集器的老年代版本。
使用多线程和“标记-整理”算法。
Parallel Old只能与Parallel Scavenger收集器一起配合使用。
 
CMS收集器
CMS收集器是一种以获得最短回收停顿时间为目标的收集器。
CMS非常适用于B/S系统服务器上,因为它的停顿时间短,GC对用户交互影响下。
CMS收集器使用“标记-清除”算法,主要分为以下几个步骤:
  • 初始标记
该步骤需要Stop The World,即停止用户线程运行。
该标记仅仅只是标记以下GC Roots能直接关联到的对象,速度很快。
  • 并发标记
是对GC Roots Tracing的过程
  • 重新标记
该步骤需要Stop The World,即停止用户线程运行。
该过程是为了修改并发标记期间因为程序继续运行而导致标记产生变化的那一步对象的标记记录。这个阶段一般比初始标记时间稍长,但是远比并发标记时间短。
  • 并发清除
耗时最长的并发标记和并发清除过程收集线程都可以与用户线程并发运行。
 
CMS收集主要优势体现在并发收集、低停顿。
CMS缺点:
  • 对CPU资源比较敏感
因为“并发标记”、“并发清除”两个步骤的收集线程与用户线程并发运行,会占用一部分CPU资源。CMS默认回收线程数(CPU数量+3)/4。
为了解决以上问题,虚拟机提供了一种新的收集器,即CMS收集器的变种(i-CMS),该收集器在并发标记、并发清除两个阶段可以让GC线程与用户新城交替运行,尽量减少GC线程的独占资源时间,这样整理GC过程会变成,但是对用户线程影响会变小。
i-CMS收集器已经被标记为过期。
  • CMS收集无法处理浮动垃圾
CMS浮动垃圾可能导致出现“Concurrent Mode Failure”失败而导致另一次Full GC的产生。
由于CMS并发清除阶段用户线程还在运行,伴随着可能产生新的垃圾,这一部分垃圾在标记后,CMS无法在当次收集中处理掉它们,只能留到下一次GC中,这一部分垃圾称为浮动垃圾。
同时垃圾清除阶段,用户线程也在并发运行,所以用户线性也需要一部分内存,导致必须为用户线程预留一部分内存,但是由于浮动垃圾的存在,可能导致下一次GC的并发清除阶段,无法预留足够的内存为用户线程使用,所以下次如果没有足够内存为用户线程使用,会出现“Concurrent Mode Failure”失败,这个失败将导致虚拟机启用备用方案,即Serial Old收集器来重新进行老年代的垃圾回收,这部分停顿时间会比较长。
  • CMS是一个基于“标记-清除”算法的垃圾回收器
标记-清除算法会产生垃圾碎片,导致内存比较零碎,如果要分配大内存的对象,可能没有足够大的内存碎片为对象分配内存。
所以CMS提供了一个配置-XX:CMSFUllGCsBeforeCompaction参数,这个参数可以设置执行多少次不压缩的Full GC后,跟着进行一次带压缩的收集。

转载于:https://www.cnblogs.com/use-D/p/10657790.html

<think>好的,我现在需要回答用户关于JVM参数配置的问题,具体是关于-XX:ReservedCodeCacheSize=800m、-XX:+UseConcMarkSweepGC和-XX:SoftRefLRUPolicyMSPerMB=50这三个参数的作用和优化。首先,我得分别分析每个参数的功能,然后结合引用资料中的信息,看看有没有相关的调优建议或者注意事项。 首先看第一个参数-XX:ReservedCodeCacheSize=800m。根据引用[1]中提到,-XX:开头的参数是非稳定参数,用于控制JVM行为,可能随版本变化。Code Cache是JVM存储编译后的本地码的区域,比如JIT编译的方法。默认大小可能不够,特别是在大量使用动态生成码的应用中,比如Spring框架或Groovy。设置这个参数为800M可以避免Code Cache被填满,导致JIT编译停止,从而影响性能。不过需要注意,设置过大可能会浪费内存资源,需要根据应用实际情况调整。 接下来是-XX:+UseConcMarkSweepGC,这是一个布尔开关参数,格式符合引用[1]中的+-Flags形式。这个参数启用CMS垃圾收集器,主要用于老年的并发标记清除。CMS的目标是减少停顿时间,适合对延迟敏感的应用。不过CMS在Java 9之后被标记为废弃,Java 14中移除,所以用户如果使用较新版本的JDK可能需要考虑替方案,比如G1GC。此外,CMS不会进行内存压缩,可能导致内存碎片,长时间运行后可能触发Full GC。需要提醒用户注意这些潜在问题,以及是否适合当前应用场景。 第三个参数是-XX:SoftRefLRUPolicyMSPerMB=50,属于引用[1]中的key=value形式。Soft Reference的回收策略,这个参数控制每MB堆内存中软引用保持活跃的毫秒数。默认值是1000,这里设为50,意味着更积极地回收软引用,释放内存。适用于需要快速释放内存防止OutOfMemoryError的场景,但可能增加GC频率,影响性能。需要平衡内存和性能,根据应用对缓存的需求调整。 接下来要考虑优化建议。对于ReservedCodeCacheSize,建议监控Code Cache的使用情况,使用JVM参数如-XX:+PrintCodeCache查看使用量,避免设置过大。对于CMS,如果JDK版本较高,建议迁移到G1GC,并监控Full GC的发生情况,可能需要调整-XX:CMSInitiatingOccupancyFraction来提前触发GC。对于SoftRefLRUPolicyMSPerMB,需评估应用对软引用缓存的依赖,适当调整该值,并监控GC日志中的软引用回收情况。 同时,用户可能需要了解如何监控这些参数的效果,比如使用JMX、GC日志分析工具(如GCViewer)或JVM内置命令如jstat。需要提醒用户在生产环境调整前进行测试,因为不同应用行为可能导致不同效果。 最后,根据用户提供的引用资料,引用[2]展示了如何查看初始JVM参数,用户可以通过类似命令检查当前Code Cache大小和GC策略。引用[3]提到了SurvivorRatio等参数,虽然不直接相关,但说明JVM参数通常需要组合调整,考虑整体内存布局。 总结每个参数的作用和优化方向,确保回答清晰,结构合理,并覆盖用户可能的后续问题,比如如何监控、替方案等。</think>### JVM参数解析与优化建议 #### 1. `-XX:ReservedCodeCacheSize=800m` **作用**: - 设置JVM码缓存区(Code Cache)的大小为800MB。码缓存用于存储JIT编译器生成的本地机器码,包括热点方法、字节码解释器等[^1]。 - **优化场景**: - 当应用频繁使用动态码生成(如Groovy、Spring AOP)时,默认的240MB(JDK8)可能不足,导致`CodeCache is full`警告并禁用JIT编译,引发性能下降。 - 建议通过`-XX:+PrintCodeCache`监控使用量,避免过度分配浪费内存。 #### 2. `-XX:+UseConcMarkSweepGC` **作用**: - 启用并发标记清除(CMS)垃圾收集器,用于老年回收,以降低GC停顿时间为目标,适合对延迟敏感的应用[^2]。 - **注意事项**: - CMS在JDK9+已废弃,JDK14+移除,建议新项目改用G1GC(`-XX:+UseG1GC`)。 - CMS不整理内存碎片,需搭配`-XX:+UseCMSCompactAtFullCollection`在Full GC时压缩内存。 - 需合理设置`-XX:CMSInitiatingOccupancyFraction=70`(默认68%)避免并发模式失败。 #### 3. `-XX:SoftRefLRUPolicyMSPerMB=50` **作用**: - 控制软引用(Soft Reference)的回收策略,公式为`存活时间 = 堆空闲内存(MB) * 参数值`。设为50表示每MB空闲堆对应软引用最多存活50ms[^1]。 - **优化场景**: - 降低该值可加速回收软引用(如缓存),避免内存不足,但可能增加缓存穿透。 - 默认值1000较保守,高内存压力场景可调低(如50-200),需结合`-Xmx`调整。 --- ### 综合优化建议 1. **监控与验证**: - 使用`jstat -gc <pid>`观察GC行为,或`jcmd <pid> Compiler.codecache`查看码缓存使用。 - 启用GC日志:`-Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps`。 2. **替方案**: - CMS替换为G1GC:`-XX:+UseG1GC -XX:MaxGCPauseMillis=200`。 - 码缓存动态调整:JDK8u+支持`-XX:+UseCodeCacheFlushing`自动清理未使用的码。 3. **参数组合示例**: ```shell -XX:ReservedCodeCacheSize=400m \ -XX:+UseG1GC \ -XX:SoftRefLRUPolicyMSPerMB=100 \ -XX:+PrintCodeCache ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值