对于Sun / Oracle的JVM,我读过GC算法将新一代划分为一个伊甸园区域和两个幸存者区域。我想知道的是,为什么有两个幸存者地区而不是一个?该算法可以在伊甸园和一个幸存者区域之间保持乒乓(目前它在两个幸存者区域之间的方式);还是这种方法有什么缺点?
对于Sun / Oracle的JVM,我读过GC算法将新一代划分为一个伊甸园区域和两个幸存者区域。我想知道的是,为什么有两个幸存者地区而不是一个?该算法可以在伊甸园和一个幸存者区域之间保持乒乓(目前它在两个幸存者区域之间的方式);还是这种方法有什么缺点?
Answers:
我相信JRockit的GC实现更像您建议的那样工作,只有一个eden和一个幸存者空间,但请不要在此引用我。
HotSpot JVM的两个生存空间的原因是为了减少处理碎片的需要。新对象分配在伊甸园空间中。一切都很好。完成后,您需要一个GC,因此请杀死陈旧的对象并将活动的对象移到幸存者空间,在那里它们可以成熟一段时间,然后提升为老一代。到目前为止还不错。但是,下次当我们用完伊甸园的空间时,我们将面临一个难题。下一个GC出现并清除了伊甸园和幸存者空间中的某些空间,但是这些空间不是连续的。所以更好
Sun对这个问题的回答是显而易见的。
在进行次要垃圾收集操作后,两个幸存者空间的作用相反
两个幸存者空间。这些保存的对象至少可以进行一次较小的垃圾回收,但是在提升为老一代之前,又有另一种变得无法访问的机会。它们中只有一个保存对象,而大多数情况下则不使用其他对象。
在次要垃圾回收操作期间,将标记已发现为垃圾的对象。可以在集合中生存的伊甸园中的活动对象被复制到未使用的生存者空间。正在使用的幸存者空间中的活动对象,将被赋予在年轻一代中进行回收的另一次机会,也将复制到未使用的幸存者空间中。最后,幸存者空间中正在使用的被认为“足够老”的活动物体被提升为老一代。
在次要垃圾回收结束时,两个幸存者空间互换角色。伊甸园完全是空的。仅使用一个幸存空间;并且老一代的入住率略有增长。因为活动对象是在其运行期间复制的,所以这种类型的垃圾收集器称为复制垃圾收集器。
资料来源:上面是Java Performance第83页的摘录,作者是Charlie Hunt和Binu John。
青年一代:是短暂居住的地方,分为两个空间:
Eden空间:新对象将在内存池中分配。假定大多数对象在创建后都会被取消引用并变得不可访问。未取消引用的对象将由新一代垃圾收集器复制到幸存空间。在某些特殊情况下,它们可能会直接复制到旧版本池中。
幸存者空间:这两个小空间保留着年轻一代垃圾收集的幸存对象。将幸存的对象从一个幸存者复制到另一个幸存者的次数很少。这允许收获我们更多被取消引用的对象。
老一代:最大的内存池,应保留长寿命的对象。一旦对象离开幸存者空间,它们就会被复制到该池中。
永久物生成:这个相当未知的池保留了所有类的信息。对于大多数应用程序,它不需要任何注意。可能需要将其修改为具有许多类的某些应用程序。如果应用程序永久加载和卸载类,则可能也需要注意。
其他优点:
请找到以下链接以获取更多详细信息,这些信息可以帮助您了解更多
标记和复制算法的实现是两个幸存者。这些在GC中用于年轻一代。作为备选方案3中提到的由Ryan这里
Java中的堆内存在称为堆内存的区域中创建的Java对象。堆内存在JVM启动时创建,堆内存在Java应用程序运行时增加或减少。当堆内存已满时,垃圾收集器将删除未使用的对象,因此垃圾收集器将为新对象腾出空间。
堆内存分为两个区域(或各代),称为
1.年轻的空间。2.旧空间。
1.在年轻空间中,有一个伊甸园空间可以容纳新物体,并且有两个幸存者空间(从和到),这两个幸存者空间的大小始终相同。
2)Survivor Spaces用于存储生存对象,当年轻空间已满时,垃圾收集器通过运行一个特殊的Young集合来删除未使用的对象,将所有在年轻空间中生存了足够长的对象提升(移动)到旧空间,从而释放年轻空间以分配更多对象。
3.如果Eden空间已满,GC将运行,如果该Eden空间中存在任何对象,则将这些对象移动到Survivor Space。
4.在年轻空间中,GC通常使用复制算法,该算法速度很快,每次将生存对象复制到其中一个生存空间中。
5.如果Survivor Space已满,则将其余活动对象直接复制到Old space。
6.在旧空间中,GC通常使用Mark-Compact算法,该算法速度较慢,但需要较少的内存。
7,当旧空间变成满垃圾时,将在其中收集一个称为旧集合的过程。
8,内存不足的情况将发生,即使为OLD或Perm部分完成GC也没有空间容纳新对象。
9,垃圾收集过程中对象被移动:伊甸园->幸存者->终身(旧空间)