面试题答案
一键面试引用计数原理
- 基本概念:在Python中,每个对象都有一个引用计数,记录了指向该对象的引用数量。
- 增加引用计数:当一个新的变量名绑定到对象,或者对象被放入容器(如列表、字典)中,对象的引用计数会增加。例如:
a = [1, 2, 3] # 列表对象引用计数加1
b = a # 列表对象引用计数再加1
c = [a] # 列表对象引用计数又加1
- 减少引用计数:当变量名被删除(使用
del
语句),或者变量名重新绑定到其他对象,或者对象从容器中移除时,对象的引用计数会减少。例如:
del a # 列表对象引用计数减1
b = [4, 5, 6] # 原列表对象引用计数再减1
c.pop() # 原列表对象引用计数又减1
- 垃圾回收:当对象的引用计数变为0时,Python垃圾回收机制会立即回收该对象所占用的内存空间。
局限性
- 循环引用问题:如果两个或多个对象相互引用,形成循环引用,即使这些对象没有外部引用,它们的引用计数也不会为0,导致无法被垃圾回收。例如:
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
del a
del b
在上述代码中,A
和B
实例相互引用,即使删除a
和b
,这两个实例对象的引用计数仍不为0,造成内存泄漏。
2. 维护引用计数的开销:每次对象的引用计数发生变化(增加或减少)时,都需要额外的CPU时间来更新引用计数,这在一定程度上增加了程序运行的开销,特别是在频繁创建和销毁对象的场景下。