Java 垃圾收集年轻一代扫描

Java 垃圾收集年轻一代扫描,java,garbage-collection,Java,Garbage Collection,我正在试图理解垃圾收集机制,我正在研究代际算法,我有一个关于年轻人和老年人之间的差异的问题。我读到,在年轻一代开始收集对象时,GC从GC根开始标记它们,以找到活的对象,通常它会将它们复制到幸存者空间,清除年轻一代区域,瞧 我不明白,如果我们从GC根开始,我们开始遍历活动对象,我们不也会在旧一代中找到对象吗?这是否意味着当我们在一个旧空间中命中一个对象时,我们在那个点上停止跟踪引用,或者什么?当GC在年轻一代中运行时,它被称为次要集合。旧代中的对象与此类型的集合无关 是的,可以从根直接访问的对象被

我正在试图理解垃圾收集机制,我正在研究代际算法,我有一个关于年轻人和老年人之间的差异的问题。我读到,在年轻一代开始收集对象时,GC从GC根开始标记它们,以找到活的对象,通常它会将它们复制到幸存者空间,清除年轻一代区域,瞧


我不明白,如果我们从GC根开始,我们开始遍历活动对象,我们不也会在旧一代中找到对象吗?这是否意味着当我们在一个旧空间中命中一个对象时,我们在那个点上停止跟踪引用,或者什么?

当GC在年轻一代中运行时,它被称为次要集合。旧代中的对象与此类型的集合无关

是的,可以从根直接访问的对象被标记为活动对象,但它们可以位于堆的其他位置,因此它们可以是旧一代中的对象

即使旧Gen对象是可访问的,次要收集也不会回收旧Gen中的垃圾

引述:

当年轻一代填满时,它会导致一个小集合 只收集年轻一代;其他地方的垃圾 世世代代都不能被收回

对我来说,这意味着GC将遍历对象图,可能会在OldGen中找到垃圾,但不会回收垃圾


我发现了这一点,这很好地解释了代间引用跟踪在HotSpot GC中是如何工作的。

尽管我没有直接检查这一点,但常识表明,每次遇到旧一代的对象时,对象图遍历都会被缩减。注意,这种检查非常便宜:对指针值进行简单的范围检查就足以确定对象在堆区域中的位置

还有一个重要的问题要考虑:如果一个年轻的物体只能通过一个旧物体来实现呢?显然,必须以某种方式考虑老一代

进入卡表:这是每个堆区域前面的一个备份结构,其中保存了该区域的压缩“位图”视图,因此每个位对应于堆的256字节。每次更新引用类型的变量时,卡片表中的相应位将提升为1,表示“脏”

卡片表就位后,每个YG集合都会发生以下情况:扫描所有标记为“脏”的堆块,寻找指向年轻一代中对象的指针。以这种方式找到的每个对象都被认为是可访问的


上述情况的腐蚀性:通过旧对象可以访问的年轻对象同时变成垃圾,将被视为可以访问并污染堆,直到发生重大GC。

谢谢Marko!你触及了我下一个问题的主题——卡片。卡区有256个字节,但据我所知,它是一个行内存,您需要知道相应的类才能从中获得意义。所以,若我们知道内存区域,我们怎么知道它包含什么或者它包含引用呢?还有什么?:)是的,我对这个问题很熟悉,但不知道细节。例如,可以扫描内存以查找对象头的封装外形。当你知道了标题,你就知道了类。此外,每个单词可能被假定为一个指针,然后取消引用以查看它是否指向有效的对象标题。这是启发式,但它可能“足够好”。我认为它不需要是启发式的。JVM可以根据每个对象头中的节点大小信息迭代对象。或者它可以记录每张卡(或一系列卡)中第一个对象头的地址,并在此基础上进行迭代。@StephenC Good points。。。记录第一个对象的地址确实给我敲响了警钟。对于跨越卡片的对象,也有一些特殊的处理方法。任何时候系统接触到旧一代对象时,它都会知道它正在这样做。我希望保存一个已被接触的老一代对象的列表比遍历所有老一代对象更便宜。但这正是我的问题,老一代对象怎么可能不关心这种类型的集合?如果它们还活着,就必须从GC根引用它们,不是吗?是的,可以从根访问OldGen对象。正如Stephen C所说,小收集不会在其他世代回收垃圾,即使它们是可以到达的。年轻一代集合不会跟踪/标记老一代中的对象。当年轻一代收集器找到从年轻到老的引用时,它将忽略该引用。