Numpy切片后原数组未被引用部分是否会被垃圾回收?
关于NumPy数组切片后的内存回收问题
好问题!这其实涉及到 NumPy 数组的**视图(view)和副本(copy)**的核心区别,以及 Python 垃圾回收机制的工作逻辑。
先看你的代码片段:
import numpy as np def foo(): x = np.ones((10,10)) return x[:5,:5] y = foo()
核心结论:原10×10数组的全部数据会暂时留在内存里
原因如下:
x[:5,:5]返回的是原数组x的视图,而非独立副本。视图不会复制原数组的底层数据,只是生成了一个新的数组对象,这个对象仅仅是“指向”原数组数据缓冲区的某一块区域。- 当函数
foo执行完毕后,局部变量x会被销毁(从函数的局部命名空间中移除),但原数组的底层数据缓冲区并没有失去所有引用——因为返回的y这个视图还在引用它。 - 因此,整个10×10数组的底层数据都会保留在内存中,直到
y也被销毁(比如执行del y,或者y脱离当前作用域),此时该数据的引用计数降到0,Python的垃圾回收器才会释放这部分内存。
如何让不需要的元素被及时回收?
如果你只想保留需要的5×5部分,让原数组的其余元素被垃圾回收,只需要返回副本而非视图:
def foo(): x = np.ones((10,10)) return x[:5,:5].copy() # 调用copy()生成独立副本
这样返回的y是一个完全独立的5×5数组,拥有自己的底层数据缓冲区。函数结束后,局部变量x指向的10×10数组因为没有任何其他引用,会被垃圾回收器立即处理,对应的内存也会被释放。
内容的提问来源于stack exchange,提问作者Nic
相关产品推荐
相关产品推荐

