周期参考是对象形成一个周期的参考,计数永远不会为0.循环参考中有两个情况。
示例如下:
Python使用“标记清除”算法来解决容器对象可能会生成的周期引用问题。在这里应注意,只有容器对象才能生成一个周期参考,例如列表,字典,用户定义的对象,用户定义的对象,,等)。简单类型(例如数字和字符串)将没有周期参考。作为优化策略,不认为仅考虑仅包含简单类型的算法。
垃圾回收时,算法分为两个步骤。
步骤1:标记阶段。在此阶段,所有对象都会行驶。如果达到它,也就是说,它引用了对象,则标记对象。
步骤2:清除阶段。再次传递对象,如果发现某个对象不可用,它将被回收。
对象将通过参考连接在一起,形成方向图。该对象构成方向图的节点,参考关系构成方向的侧面。从根对象开始,沿着根对象沿着侧面横穿侧面的对象,可可标记为事件对象。在这里是根对象,它指的是一些全局变量,呼叫和寄存器。这些对象无法删除。
如上图所示,我们将黑色圆视为根对象。从中开始,可以标记对象1,然后标记,对象2和3间接的间接,而4和5则无法访问。然后1、2和3是活动的对象。
在标记算法中,为了跟踪容器对象,每个容器对象都需要维护两个其他指针,以形成容器对象的双端链接列表,而指针指向两个容器对象,这很方便插入Python解释器维护两个这样的两个末端链接列表。一个链接列表A存储需要扫描的容器对象,另一个B暂时存储。
对于链接列表中的每个对象,除了当前参考数变量ref_count的记录记录外,还有一个gc_ref variable.gc_ref变量是ref_count的副本。
当GC启动时,它将在链接列表中一一遍历前容器对象,并将当前对象的所有参考对象的GC_REF值最小化。然后将参考计数提起。gc然后在此处扫描所有容器对象。如果对象的对象为0,则将该对象标记为gc_tentavely_unreachable并移至链接列表B.如果对象的对象不是0,则对象将被标记为gc_reach.in。在将所有节点标记为gc_reachable,如果该节点当前在链接列表B中,则需要将其移动到链接列表A.这次,此次,链接中存在的容器对象列表B是真正需要发布的对象。
在上述阶段,将暂停整个应用程序,并在清除标记后恢复应用程序段操作。
标记清晰算法的优点是它可以解决周期参考的问题,并且在执行整个算法期间没有其他开销。缺点是在清除执行时阻止了正常程序。,在清除标签多次之后,程序的桩空间将产生一些小的内存片段。