Java 为什么主要垃圾收集比次要垃圾收集慢?

Java 为什么主要垃圾收集比次要垃圾收集慢?,java,garbage-collection,Java,Garbage Collection,经历了这一切,但仍然 不清楚在次要和主要GC收集中实际发生了什么 假设我在年轻一代有100个对象,其中85个对象是无法到达的对象。现在当小GC运行时, 它将回收85个对象的内存,并将15个对象移动到较旧(终身)的一代 现在,老一代中存在15个活动对象,其中3个无法访问。比如说主要的GC发生了。它将保持 15个对象,并为3个无法访问的对象回收内存。据说大GC比小GC慢

经历了这一切,但仍然 不清楚在次要和主要GC收集中实际发生了什么

假设我在年轻一代有100个对象,其中85个对象是无法到达的对象。现在当小GC运行时, 它将回收85个对象的内存,并将15个对象移动到较旧(终身)的一代

现在,老一代中存在15个活动对象,其中3个无法访问。比如说主要的GC发生了。它将保持 15个对象,并为3个无法访问的对象回收内存。据说大GC比小GC慢<我的问题是为什么?这是因为主GC发生的对象通常比次GC发生的对象多,因为次GC发生的频率比主GC发生的频率高吗?

根据理解,主要GC应该更快,因为它需要做的工作更少,即从无法访问的对象中回收内存,而不是次要GC,因为 年轻一代死亡率高

1)次要GC将首先将15个对象移动到一个幸存者空间,例如SS1,下一个GC将把仍然活着的对象移动到SS2,下一个GC将把幸存的对象移回SS1,依此类推。只有那些在几次(如8次)搬迁(小型地面军事系统)中幸存下来的人才会最终进入老一代

2) 只有当JVM无法在旧一代中分配对象时,才会发生主要GC,因为在旧一代中没有可用空间。为了从死掉的对象中清除内存,GC会遍历旧一代中的所有对象,因为旧一代比新一代大好几倍,它可能会容纳好几倍的对象,所以GC处理将花费好几倍的时间

我的问题是为什么?这是因为主GC发生的对象通常比次GC发生的对象多,因为次GC发生的频率比主GC发生的频率高吗

你简直是一针见血。从Oracle的文章中,强调我的:

通常,主集合的速度要慢得多,因为它涉及所有活动对象

因此,大型GC不仅分析旧一代中的15个对象,还分析年轻一代(再次)以及堆中的permgen和GC区域。Minor GC只分析年轻一代,因此通常不会有那么多对象可供查看

据了解,主要GC应该更快,因为它需要比次要GC做更少的工作(即从无法访问的对象中回收内存),因为年轻一代的死亡率很高

我想我理解你为什么这么想。我可以想象,当对象升级到几乎完整的旧一代时,主GC可以在次GC之后很快运行。因此,年轻一代(大概)不会包含太多的对象来收集


但是,如果我没有记错的话,老一代通常比年轻一代大,因此GC不仅需要分析更多的空间,还需要再次检查permgen,以及年轻一代中的剩余对象(再次)。这可能就是为什么大型GC速度较慢的原因——仅仅是因为有更多的事情要做。通过改变代空间的大小,使年轻一代比老一代和permgen都大,您可能可以使主要GC比次要GC更快,但我认为这不是一个常用的设置…

我对这一点产生了怀疑,两天之后终于得到了答案,感谢叶夫吉尼·多洛菲夫。如果可能的话,你能帮我吗