为了针对这种情况进行优化,内存是分代管理的(存储着不同年龄对象的内存池)。当世代填满时,垃圾收集会在每个世代中发生。绝大多数对象分配在专用于年轻对象(年轻一代)的池中,并且大多数对象在那里死亡。 GC如何为不从任何对象使用到正在运行的程序的对象定义时间? GC如何确定将对象从年轻一代转移到老一代?
答案 0 :(得分:0)
我很难确切地知道您在这里寻找什么样的答案。但是简短的答案是,当对象的分配空间已满时,对象会移动。
年轻一代的分配空间通常很小,并且通常会很快填满-大约每秒一次,具体取决于应用程序的类型。由于绝大多数对象的生存期都很短,因此运行时仅查找仍可访问的少数对象,并将它们移到幸存者空间。然后将整个年轻一代空间清除干净,并重新开始分配。
通常有两个幸存者空间,当一个幸存者空间已满时,其中的对象将移至另一个。在移动了几次之后,该对象将改为移动到使用期限的对象堆,该堆通常由另一种GC算法(通常是某种标记清除过程)来管理。
如果通过运行代码无法访问对象,则该对象实际上不再存在。不要将垃圾收集器视为寻找不再可访问的对象并删除它们的对象,相反,正确的思维模式是,垃圾收集器会持续保持是的对象快死了可以到达。如果垃圾收集器停止关注某个对象,它将自行消失:内存将被重用于其他目的。
您可能会喜欢Raymond Chen从Everybody thinks about garbage collection the wrong way和When does an object become available for garbage collection?开始的一系列博客文章
答案 1 :(得分:0)
年轻一代想像栈。对象将在当前堆栈指针处分配,并且指针将按已分配的对象大小移动(这确实非常快)。
当指针到达Eden空间内存范围的顶部时,需要发生次要GC。要跟踪所有活动对象,收集器将从创建根集开始。这是可从程序直接访问的所有对象的列表。收集器通过扫描寄存器和程序堆栈以查找对象引用来完成此操作。这些对象中的每一个都将被标记为活动对象,然后扫描它们所包含的对象引用,以获取您在其中定义的变量。这会递归发生,直到标记了可以从您的代码访问的所有对象为止。
完成后,伊甸园空间中的所有活动对象都会复制到空的(幸存者)空间。同样在这时,任何仍然存在于(从)幸存者空间中的对象都将被复制到幸存者空间中,除非它们已达到使用期限阈值,在这种情况下,它们将被提升(复制)到老一代中。
要具体回答您的问题,由于上述算法,对象在年轻一代中花费的时间将取决于几个因素。
上一代的集合可以使用几种不同算法中的一种,但是确定哪些对象仍然存在的方法与年轻一代相同,即创建一个根集,然后递归扫描所有对象引用。