2013-02-13 74 views
4

我有一个关于Numpy阵列内存管理的问题。假设我创建使用以下的缓冲一个numpy的数组:为“S”Numpy阵列内存管理

>>> s = "abcd" 
>>> arr = numpy.frombuffer(buffer(s), dtype = numpy.uint8) 
>>> arr.flags 
    C_CONTIGUOUS : True 
    F_CONTIGUOUS : True 
    OWNDATA : False 
    WRITEABLE : False 
    ALIGNED : True 
    UPDATEIFCOPY : False 
>>> del s # What happens to arr? 

在上面的情况下,是“ARR”持有参考?如果我删除's',这会释放为's'分配的内存,从而使'arr'潜在地引用未分配的内存?

我有一些其他问题:

  • 如果这是有效的,Python是怎样知道什么时候,以释放的'分配的内存? gc.get_referrents(arr)函数似乎没有显示'arr'持有对's'的引用。
  • 如果这是无效的,我如何注册's'到'arr'的引用,以便Python GC在它的所有引用都不存在时自动收获'?'

回答

5

下应该澄清的事情一点:

>>> s = 'abcd' 
>>> arr = np.frombuffer(buffer(s), dtype='uint8') 
>>> arr.base 
<read-only buffer for 0x03D1BA60, size -1, offset 0 at 0x03D1BA00> 
>>> del s 
>>> arr.base 
<read-only buffer for 0x03D1BA60, size -1, offset 0 at 0x03D1BA00> 

在第一种情况下del s没有任何影响,因为什么阵列指向的是它创造了一个buffer,这不是其他地方引用。

>>> t = buffer('abcd') 
>>> arr = np.frombuffer(t, dtype='uint8') 
>>> arr.base 
<read-only buffer for 0x03D1BA60, size -1, offset 0 at 0x03C8D920> 
>>> arr.base is t 
True 
>>> del t 
>>> arr.base 
<read-only buffer for 0x03D1BA60, size -1, offset 0 at 0x03C8D920> 

在第二种情况下,当你del t,你摆脱变量t指向buffer对象,但由于阵列仍具有相同buffer参考,它不会被删除。虽然我不确定如何检查它,但如果您现在del arrbuffer对象应该丢失其最后一个参考并自动垃圾收集。

+0

在这两种情况下,您都可以使用CPython中的sys.getrefcount来监视's'的refcount增量。不重要的是,它当然是有效的。 – seberg 2013-02-14 10:39:54