并行清理
今天,我们介绍了并行GC的工作原理。 具体来说,这是在Eden上运行Parallel Scavenge收集器,在Tenured一代中运行Parallel Mark and Sweep收集器的组合。 您可以通过传递-XX:+ UseParallelOldGC来获得此选项,尽管它是某些计算机类型的默认选项。
如果您还没有读过我的第一本有关垃圾收集的博客文章,因为这没有概述。
伊甸园和幸存者空间
在平行的扫气收集器中,使用称为半球GC的方法收集伊甸园和幸存者空间。 对象最初是在Eden中分配的,一旦Eden接近全1 ,就会触发gc的Eden空间。 这样可以识别活动物体并将其复制到活动的“幸存者空间” 2中 。 然后,它将整个Eden空间视为一个空闲的,连续的内存块,可以再次分配到该内存块中。
在这种情况下,分配过程就像切碎切达干酪一样结束。 每个块都被连续切开,然后旁边的切片将被“吞噬”。 这样做的好处是分配只需要添加指针即可。
为了识别有生命的物体,进行物体图的搜索。 搜索从一组“根”对象开始,这些对象是可以保证存在的对象,例如,每个线程都是一个根对象。 然后,搜索将找到由根集指向的对象,并向外扩展直到找到所有活动对象。 这是一个非常好的绘画作品,由Michael Triana提供
在并行清除的上下文中,并行表示收集是由同时运行的多个线程完成的。 这不应与增量GC混淆,增量式GC的收集器与程序同时运行或交错运行。 通过更好地使用现代多核CPU,并行收集可提高整体GC吞吐量。 通过为每个线程提供一组要标记的根以及对象表的一部分来实现并行性。
有两个幸存者空间,但是在任何时间点只有一个处于活动状态。 它们的收集方式与伊甸园相同。 这个想法是,当物体从伊甸园提升时,它们会被复制到活跃的幸存者空间中。 然后,当需要疏散空间时,将它们复制到非活动幸存者空间。 一旦活动幸存者空间被完全撤离,则非活动空间变为活动状态,而活动空间变为非活动状态。 这是通过将指针翻转到幸存者空间的开头来实现的,这意味着可以释放幸存者空间中的所有死对象,而只需分配给单个指针即可。
年轻一代的设计和时间权衡
由于这仅涉及复制活动对象并且指针更改,因此收集伊甸园和幸存者空间所花费的时间与活动对象的数量成比例。 这是非常重要的,因为由于世代的假设,我们知道大多数对象都死于年轻,因此释放与它们相关联的内存没有GC成本。
幸存空间的设计受到这样一种想法的启发:年轻时收集对象比收集长期使用的空间要便宜。 在几次GC运行中,以半球方式继续收集对象有助于整体吞吐量。
最后,伊甸园被组织成一个连续的空间,这使得对象分配便宜。 AC程序可能会重新使用“ malloc”命令来分配一块内存,这涉及遍历内存中的可用空间列表,以尝试找到足够大的空间。 当您使用竞技场分配器并连续分配时,您需要做的就是检查是否有足够的可用空间,然后将指针增加该对象的大小。
平行标记和扫掠
在一定数量的收藏中幸存下来的对象就进入了租用空间。 他们生存所需的次数称为“任职期限”。 使用称为标记和清除的算法,保有权集合的工作方式与Eden有所不同。 每个对象都有一个与之关联的标记位。 标记最初全部设置为false,并且在图形搜索过程中到达对象时将其设置为true。
标识活动对象的图形搜索类似于为年轻一代描述的搜索。 区别在于,它不是复制活动对象,而是对其进行标记。 之后,它可以遍历对象表并释放所有不存在的对象。 该过程由多个线程并行完成,每个线程都搜索堆的一个区域。
不幸的是,删除不活动对象的过程使使用期空间看起来像瑞士奶酪。 您会在对象所在的位置获得一些已使用的内存,以及对象之前所在的位置之间的差距。 这种碎片化对应用程序性能没有帮助,因为它使分配大于Kong大小的对象成为不可能。
为了减少Swiss Cheese的问题,并行标记/扫描将堆压缩到较小的位置,以尝试在占位空间的开始处连续分配活动对象。 删除后,它搜索租用空间的区域,以识别占用率低和占用率高的区域。 来自占用率较低区域的活动对象向下移至占用率较高的区域。 这些自然位于上一个压缩阶段的内存较低端。 在此阶段中,对象的移动实际上是由分配给目标区域而不是源区域的线程执行的。
摘要
- 并行Scavenge将堆拆分为4个空间:伊甸园,两个幸存者空间和终身使用空间。
- 并行Scavenge使用并行复制收集器到收集器Eden和Survivor Spaces。
- 租用空间使用了不同的算法。 这会标记所有活动对象,删除不活动的对象,然后压缩空间/
- 并行Scavenge具有良好的吞吐量,但是在运行时会暂停整个程序。
在第三部分中,我将介绍CMS或Concurrent-Mark-Sweep收集器的工作方式。 希望对乳制品过敏的人更容易阅读这篇文章。
- 从技术上讲,每个堆空间都有一个“占用阈值”,它定义了在收集发生之前允许空间达到多少。
- 该复制算法基于Cheney算法 。
翻译自: https://www.javacodegeeks.com/2013/06/garbage-collection-in-java-2.html