MST

星途 面试题库

面试题:Python垃圾回收机制中标记清除算法的原理及应用场景

请阐述Python垃圾回收机制里标记清除算法是如何工作的,在哪些实际编程场景下,这种算法能够有效避免内存泄漏问题?
28.7万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

标记清除算法工作原理

  1. 标记阶段
    • Python 会在堆内存中维护一个双向链表,用于管理所有对象。垃圾回收器从根对象集合(如全局变量、栈上的变量等)出发,通过引用关系遍历整个对象图。
    • 对于每一个可达的对象(即从根对象通过引用链能够访问到的对象),垃圾回收器会为其设置一个标记位,标记该对象为存活对象。
  2. 清除阶段
    • 标记完成后,垃圾回收器再次遍历堆内存中的所有对象。
    • 对于那些没有被标记(即标记位未设置)的对象,垃圾回收器认为这些对象是不可达的,也就是垃圾对象,会将这些对象所占用的内存空间回收,并将其从对象链表中移除。

有效避免内存泄漏场景

  1. 循环引用场景
    • 当两个或多个对象相互引用,形成循环引用时,如果没有标记清除算法,这些对象即使在程序逻辑上不再被需要,也无法被正常回收,从而导致内存泄漏。
    • 例如,在Python中,如下代码:
class A:
    def __init__(self):
        self.b = None


class B:
    def __init__(self):
        self.a = None


a = A()
b = B()
a.b = b
b.a = a
a = None
b = None
  • 这里ab对象相互引用,在将ab赋值为None后,这两个对象已经没有外部引用,但由于循环引用,如果没有标记清除算法,它们不会被回收。标记清除算法通过从根对象出发标记可达对象,这两个相互引用但从根不可达的对象不会被标记,最终会在清除阶段被回收,有效避免了这种因循环引用导致的内存泄漏。
  1. 复杂数据结构内部引用场景
    • 在一些复杂的数据结构,如嵌套的列表、字典或自定义的复杂类结构中,内部对象之间可能存在复杂的引用关系。
    • 例如,一个多层嵌套的字典结构,当外部对这个字典的引用被删除后,字典内部对象之间的引用可能使得这些对象无法被正常回收。标记清除算法能够从根对象遍历到这些复杂结构内部的对象,正确标记存活对象,回收不可达对象,避免内存泄漏。