parNew+CMS,在minorGC发生前

本文探讨了ParNew与CMS垃圾回收器之间的交互机制,特别是当ParNew在收集过程中遇到晋升失败时,如何触发CMS或其他全堆收集器的介入。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作者:RednaxelaFX 

链接:http://hllvm.group.iteye.com/group/topic/42365



ParNew/CMS组合在一起用的时候, 
ParNewGeneration::collect(): 
http://hg.openjdk.java.net/jdk7u/jdk7u/hotspot/file/312b5f1dc31d/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp#l948

C++代码   收藏代码
  1. // If the next generation is too full to accommodate worst-case promotion  
  2. // from this generation, pass on collection; let the next generation  
  3. // do it.  
  4. if (!collection_attempt_is_safe()) {  
  5.   gch->set_incremental_collection_failed();  // slight lie, in that we did not even attempt one  
  6.   return;  
  7. }  


collection_attempt_is_safe()的定义在基类DefNewGeneration里: 
http://hg.openjdk.java.net/jdk7u/jdk7u/hotspot/file/312b5f1dc31d/src/share/vm/memory/defNewGeneration.cpp#l865
这里它基本上就是交给CMS的ConcurrentMarkSweepGeneration::promotion_attempt_is_safe(size_t max_promotion_in_bytes)去计算最大可能晋升的对象大小跟CMS generation剩余空间的关系: 
http://hg.openjdk.java.net/jdk7u/jdk7u/hotspot/file/312b5f1dc31d/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp#l898
C++代码   收藏代码
  1. bool ConcurrentMarkSweepGeneration::promotion_attempt_is_safe(size_t max_promotion_in_bytes) const {  
  2.   size_t available = max_available();  
  3.   size_t av_promo  = (size_t)gc_stats()->avg_promoted()->padded_average();  
  4.   bool   res = (available >= av_promo) || (available >= max_promotion_in_bytes);  
  5.   return res;  
  6. }  

也就包含了楼主所问的检查:之前平均晋升的对象大小、当前young generation已使用的大小(也就是最大可能晋升的对象大小)跟当前CMS的最大可用空间大小相比较。只要CMS的剩余空间比前两者的任意一者大,CMS就认为晋升还是安全的;反之亦然。 

楼主所问的“之前每次晋升到老年代的平均大小大于年老代的剩余空间大小”如果外加“当前minor GC时ParNew里已使用空间同样大于CMS年老代的剩余空间大小”,那么ParNew的minor GC就会在通知CMS说“我不干了”之后直接跳过自己。 

这样就会回到GenCollectedHeap::do_collection()的循环里。GCH发现ParNew不干了之后会问CMS年老代要不要收集,CMS基本上只能回答:要。 
然后CMS会根据 UseCMSCompactAtFullCollection CMSFullGCsBeforeCompaction 和当前收集状态去决定是: (1) 使用跟Serial Old GC一样的LISP2算法的mark-compact来做full GC ,还是  (2) 用CMS自己的mark-sweep来做不并发的(串行的)old generation GC 。后者在CMS里也叫做foreground collector(正常的并发模式的CMS是background collector)。 
http://hg.openjdk.java.net/jdk7u/jdk7u/hotspot/file/312b5f1dc31d/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp#l1933

如果发生晋升失败的时候CMS已经正在执行一个并发收集,那么那个并发收集就会被打断,各种状态复位之后转为执行上面选择的两种串行收集之一。 

UseCMSCompactAtFullCollection默认为true,CMSFullGCsBeforeCompaction默认是0,这样的组合保证CMS默认不使用foreground collector,而是用Serial Old GC的方式来在promotion failed或者可能会fail的时候进行full GC。 
JDK9的一个新变更就要去掉这两个参数及其背后的代码,彻底去掉CMS的foreground GC功能: JEP 214: Remove GC Combinations Deprecated in JDK 8 。为了与未来接轨大家也请不要乱配置这俩参数了喔。 

要注意上述两种可能性不但算法不一样,收集的范围也不一样。 

Serial Old GC的算法是mark-compact(也可以叫做mark-sweep-compact,但要注意它不是“mark-sweep”)。具体算法名是LISP2。它收集的范围是整个GC堆,包括Java heap的young generation和old generation,以及non-Java heap的permanent generation。因而它是full GC。 

CMS的foreground collector的算法就是普通的mark-sweep。它收集的范围只是CMS的old generation,而不包括其它generation。因而它在HotSpot VM里不叫做full GC。 

======================================== 

顺带一提,如果在ParNew准备收集时CMS说晋升没问题,但ParNew已经开始收集之后确实遇到了晋升失败的情况,最终的处理跟上面的流程基本一样。

<think>好的,我现在要回答用户关于Minor GC和Young GC的不同之处的问题。首先,我需要确认这两个术语的定义以及它们在Java虚拟机(JVM)中的具体应用。 用户可能已经了解一些GC的基本概念,但可能存在混淆,因为不同资料中术语的使用可能不一致。我的任务是明确这两个术语是否指代同一概念,或者存在差异。首先,我需要回顾JVM的垃圾回收机制,尤其是分代收集理论。 根据分代假说,大多数对象很快变得不可达,因此堆内存通常分为年轻代(Young Generation)和老年代(Old Generation)。年轻代进一步分为Eden区、Survivor区(From和To)。当Eden区满时,会触发针对年轻代的垃圾回收,这就是通常所说的Minor GC。而Young GC,从字面意义上看,应该也是指年轻代的垃圾回收,所以可能两者是同一概念的不同称呼。 不过,可能存在一些资料或特定上下文中,这两个术语被用来区分不同的情况。例如,是否包括Survivor区的处理,或者是否与其他类型的GC(如Major GCFull GC)对比时使用的术语不同。我需要查阅权威资料或官方文档来确认这一点。 查阅Oracle的官方文档和《深入理解Java虚拟机》一书,发现通常将针对年轻代的回收称为Minor GC,而Young GC可能是一个更口语化的表达,指同一过程。另外,有时候Young GC可能特指年轻代内部的回收,而Minor GC可能有时会被误用来指代其他情况,但通常两者是等同的。 需要进一步确认是否有其他上下文中的区别,比如不同的垃圾收集器实现是否使用不同的术语。例如,在G1垃圾收集器中,可能有不同的区域划分,但年轻代的回收仍然称为Young GC或Minor GC。此外,是否存在某些情况下Minor GC包括部分老年代的回收,但这可能涉及到跨代引用等问题,通常Minor GC专注于年轻代。 总结来看,用户的问题可能源于术语的不同使用,而实际上Minor GC和Young GC指的是同一过程。但为了全面回答,我需要指出可能的细微差别,例如不同资料中的用词习惯,或者某些特定场景下的不同解释。此外,可能用户听到的不同术语导致混淆,需要明确它们是否同义,或者在特定上下文中有不同含义。 接下来,我需要组织回答结构,首先明确两个术语的定义,然后指出它们是否相同,如果有区别的话具体在哪里,可能存在的不同解释,最后总结建议。同时,要使用用户提供的格式要求,如行内数学公式用$...$,独立公式用$$...$$,但这个问题可能不需要数学公式,所以可以忽略这部分。确保回答结构清晰,分点说明,帮助用户逐步理解。</think>--- ### **一、术语定义与核心关系** 在JVM垃圾回收机制中,**Minor GC** 和 **Young GC** 本质上是**同一个过程的不同表述**,均指针对**年轻代(Young Generation)** 的垃圾回收。以下从多角度分析其一致性及可能的细微差异: --- ### **二、为什么说两者是同一概念?** 1. **操作对象一致** - 两者均针对年轻代(Eden + Survivor区)进行垃圾回收。 - 触发条件相同:**Eden区空间不足**时启动。 2. **执行目标一致** - 核心目标:回收短暂存活的对象,将存活对象晋升至Survivor区或老年代。 - 算法相似:通常采用**复制算法(Copying)**,将Eden和From Survivor区的存活对象复制到To Survivor区。 3. **官方文档与权威资料** - Oracle官方文档、《深入理解Java虚拟机》等均将两者视为同一概念。 - 示例: ```plaintext Minor GC(即Young GC)负责回收年轻代内存。 ``` --- ### **三、可能的“差异”来源** 尽管两者本质相同,但某些场景下可能因**上下文习惯**或**特定垃圾收集器实现**导致术语侧重不同: 1. **上下文习惯差异** - **Minor GC**:强调“小型”回收(与Full GC对比),突出回收规模较小、耗时短。 - **Young GC**:强调回收区域(年轻代),与Old GC(老年代回收)形成明确区分。 2. **垃圾收集器实现差异** - **G1收集器**:可能使用 **Young GC** 特指年轻代Region的回收,而 **Mixed GC** 包含年轻代和部分老年代Region。 - **CMS收集器**:通常直接使用 **Minor GC** 描述年轻代回收,与老年代的并发回收(Concurrent Mark-Sweep)区分。 --- ### **四、对比表格** | 特性 | Minor GC | Young GC | |---------------------|-----------------------------------|-----------------------------------| | **核心定义** | 针对年轻代的垃圾回收 | 针对年轻代的垃圾回收 | | **术语侧重点** | 强调回收规模(小型) | 强调回收区域(年轻代) | | **常见使用场景** | 传统分代收集器(如Serial、CMS) | 现代收集器(如G1)或强调区域时使用 | | **算法** | 复制算法 | 复制算法 | | **触发条件** | Eden区空间不足 | Eden区空间不足 | --- ### **五、误区澄清** 1. **与Major GC/Full GC的关系** - **Major GC**:通常指老年代垃圾回收(Old GC),但定义模糊,部分资料将其等同于Full GC。 - **Full GC**:回收整个堆(年轻代 + 老年代 + 元空间),与Minor/Young GC有本质区别。 2. **晋升过程的归属** - Minor/Young GC期间,若存活对象年龄超过阈值(`-XX:MaxTenuringThreshold`)或Survivor区空间不足,会晋升到老年代。 - **晋升行为属于Minor/Young GC的一部分**,而非独立阶段。 --- ### **六、示例流程(以ParNew收集器为例)** 1. **触发条件** - Eden区分配新对象失败(空间不足)。 2. **执行步骤** - **STW暂停**:暂停所有用户线程。 - **标记存活对象**:从GC Roots出发标记Eden和From Survivor区的存活对象。 - **复制对象**:将存活对象复制到To Survivor区,年龄+1;年龄超限则晋升至老年代。 - **清理内存**:清空Eden和From Survivor区,交换From/To Survivor角色。 3. **耗时特征** - 通常为毫秒级,具体取决于年轻代大小和存活对象数量。 --- ### **七、总结** - **Minor GC = Young GC**:两者是同一过程的两种表述,均针对年轻代垃圾回收。 - **术语差异**:仅在使用习惯或特定垃圾收集器上下文中有细微侧重,无本质区别。 - **优化建议**:关注年轻代大小(`-XX:NewRatio`)、Survivor区比例(`-XX:SurvivorRatio`)等参数,减少晋升频率,避免频繁GC
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值