垃圾收集如何确定收集垃圾对象的时间以及对象从年轻一代推到老一代需要多长时间?

时间:2018-12-03 16:09:27

标签: garbage-collection

为了针对这种情况进行优化,内存是分代管理的(存储着不同年龄对象的内存池)。当世代填满时,垃圾收集会在每个世代中发生。绝大多数对象分配在专用于年轻对象(年轻一代)的池中,并且大多数对象在那里死亡。 GC如何为不从任何对象使用到正在运行的程序的对象定义时间? GC如何确定将对象从年轻一代转移到老一代?

2 个答案:

答案 0 :(得分:0)

我很难确切地知道您在这里寻找什么样的答案。但是简短的答案是,当对象的分配空间已满时,对象会移动。

年轻一代的分配空间通常很小,并且通常会很快填满-大约每秒一次,具体取决于应用程序的类型。由于绝大多数对象的生存期都很短,因此运行时仅查找仍可访问的少数对象,并将它们移到幸存者空间。然后将整个年轻一代空间清除干净,并重新开始分配。

通常有两个幸存者空间,当一个幸存者空间已满时,其中的对象将移至另一个。在移动了几次之后,该对象将改为移动到使用期限的对象堆,该堆通常由另一种GC算法(通常是某种标记清除过程)来管理。

如果通过运行代码无法访问对象,则该对象实际上不再存在。不要将垃圾收集器视为寻找不再可访问的对象并删除它们的对象,相反,正确的思维模式是,垃圾收集器会持续保持的对象快死了可以到达。如果垃圾收集器停止关注某个对象,它将自行消失:内存将被重用于其他目的。

您可能会喜欢Raymond Chen从Everybody thinks about garbage collection the wrong wayWhen does an object become available for garbage collection?开始的一系列博客文章

答案 1 :(得分:0)

年轻一代想像栈。对象将在当前堆栈指针处分配,并且指针将按已分配的对象大小移动(这确实非常快)。

当指针到达Eden空间内存范围的顶部时,需要发生次要GC。要跟踪所有活动对象,收集器将从创建根集开始。这是可从程序直接访问的所有对象的列表。收集器通过扫描寄存器和程序堆栈以查找对象引用来完成此操作。这些对象中的每一个都将被标记为活动对象,然后扫描它们所包含的对象引用,以获取您在其中定义的变量。这会递归发生,直到标记了可以从您的代码访问的所有对象为止。

完成后,伊甸园空间中的所有活动对象都会复制到空的(幸存者)空间。同样在这时,任何仍然存在于(从)幸存者空间中的对象都将被复制到幸存者空间中,除非它们已达到使用期限阈值,在这种情况下,它们将被提升(复制)到老一代中。

要具体回答您的问题,由于上述算法,对象在年轻一代中花费的时间将取决于几个因素。

  1. 伊甸园空间有多大(空间越大,填充所需的时间就越长)
  2. 实例化新对象的速度(执行速度越快,伊甸园空间将被填满的速度越快)。
  3. 任期阈值。这是一个对象在升级到老一代之前将在幸存者空间之间复制多少次。
  4. 幸存者空间的大小也将起一定作用,因为如果这些对象填满,它们将被更快地提升

上一代的集合可以使用几种不同算法中的一种,但是确定哪些对象仍然存在的方法与年轻一代相同,即创建一个根集,然后递归扫描所有对象引用。