面试题答案
一键面试闭包对内存管理的影响
- 闭包定义:在Python中,闭包是指一个函数对象,它可以访问其定义时所在的作用域中的变量,即使该作用域在函数调用时已经不存在。例如:
def outer():
x = 10
def inner():
return x
return inner
func = outer()
这里inner
函数就是一个闭包,它引用了outer
函数作用域中的变量x
。
2. 内存影响:闭包会使得被引用的自由变量(如上述例子中的x
)的生命周期延长。因为闭包持有对这些自由变量的引用,即使outer
函数执行完毕,其局部作用域本应被销毁,但由于闭包的存在,x
所占用的内存不会被立即释放,从而影响了内存管理。
闭包内函数对象生命周期结束时自由变量的情况
- Python垃圾回收机制:Python采用引用计数为主,标记 - 清除和分代收集为辅的垃圾回收机制。引用计数是指每个对象都维护一个引用计数,当引用计数变为0时,对象内存会被释放。
- 自由变量的命运:当闭包内的函数对象生命周期结束时,如果没有其他地方引用该闭包,那么闭包的引用计数会降为0,此时闭包对象会被垃圾回收机制回收。同时,如果闭包是自由变量的最后一个引用,那么自由变量的引用计数也会降为0,自由变量所占用的内存也会被释放。例如:
def outer():
x = [1, 2, 3] # 这里用列表是为了方便观察对象引用
def inner():
return x
return inner
func = outer()
func = None # 此时闭包对象的引用计数变为0,闭包对象会被回收
# 如果闭包是x的最后一个引用,x也会被回收
但如果在闭包外还有其他地方引用了自由变量,那么自由变量的引用计数不会降为0,其内存不会被释放。例如:
def outer():
x = [1, 2, 3]
def inner():
return x
return inner
func = outer()
y = func() # y引用了自由变量x
func = None # 闭包对象引用计数变为0被回收,但x因y的引用,不会被回收