【问题标题】:Numpy: garbage collection after slicingNumpy:切片后的垃圾收集
【发布时间】:2018-10-05 04:54:56
【问题描述】:
def foo():
    x = np.ones((10,10))
    return x[:5,:5]

如果我调用y = foo(),我将得到一个 5x5 数组(x 中值的 1/4)。但是x 中的其他值会发生什么情况,它们是保留在内存中还是以某种方式收集垃圾?我想明白这一点。

【问题讨论】:

  • 可能有用的读物​​:Python garbage collector documentation
  • NumPy 数组的基本切片会创建一个数组视图,该视图保留对原始数组的引用。必须保留原始数组以使切片有意义。只要它的切片视图存在,名为x 的数组就会一直存在。见docs.scipy.org/doc/numpy-1.13.0/reference/arrays.indexing.html
  • @kindall 你有这方面的参考吗?我对 numpy 内部结构不是很熟悉,有兴趣了解更多
  • 我发布的链接概述了基本索引与高级索引,并指出基本索引创建了一个视图。

标签: python numpy memory-leaks garbage-collection numpy-ndarray


【解决方案1】:

正如 kindall 在 cmets 中所说,NumPy 数组上的 basic slicing 创建原始数组的视图。视图必须保持整个原始对象处于活动状态;您可以在视图的 base 属性中看到它用于执行此操作的引用。

In [2]: x = numpy.ones((10, 10))

In [3]: y = x[:5, :5]

In [4]: y.base is x
Out[4]: True

【讨论】:

  • 值得注意的是y = y.copy()会导致x被清理
  • 即使 x 超出范围?
  • @Nic:对象生命周期没有范围。变量有作用域,但变量不是对象。
  • x不是指向ndarray的变量吗?当x 超出范围时,垃圾收集器不会对其调用某种处置函数吗?这是我的问题 - 是否因为 y 而保留了整个 ndarray?
  • 是的,由于y,整个数组都被保留了。这里不涉及垃圾收集器;这是一个简单的引用计数案例。 x 是对数组的引用,y 是包含对数组的引用的视图。当x 消失时,y 中的某处仍有引用。数组在其引用计数为零之前不会被处理掉,但事实并非如此。但是,如果 y 超出范围,视图将被释放,这将允许数组被释放。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-04-10
  • 2014-02-23
  • 2015-02-11
  • 1970-01-01
  • 2011-01-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多