2

我使用 python 已经有很长一段时间了,我对垃圾收集、内存管理以及删除变量和释放内存的实际处理方面的一些问题感到困惑。

>>> pop = range(1000)
>>> p = pop[100:700]
>>> del pop[:]
>>> pop
[]
>>> p
[100.. ,200.. 300...699]

在上面的代码中,发生了这种情况。但,

>>> pop = range(1000)
>>> k = pop   
>>> del pop[:]
>>> pop 
[]
>>> k
[]

在第二种情况下,这意味着 k 只是指向列表“pop”。

问题的第一部分:

但是,第一个代码块中发生了什么?包含 [100:700] 元素的内存没有被删除还是在创建列表“p”时重复?

问题的第二部分:

此外,我尝试在可能的情况下在两者之间包含 gc.enable 和 gc.collect 语句,但是这两个代码中的内存利用率都没有变化。这有点令人费解。python没有将空闲内存返回给操作系统,这不是很糟糕吗?如果我在我所做的小研究中错了,请纠正我。提前致谢。

4

2 回答 2

5

对序列进行切片会产生一个新序列,其中包含适当元素的浅表副本。

将内存返回给操作系统可能会很糟糕,因为脚本可能会转身并创建新对象,此时 Python 将不得不再次向操作系统请求内存。

于 2012-06-26T09:10:28.180 回答
1

第一部分:

在第一个代码块中,您创建一个新对象,在删除旧对象之前复制旧对象的元素。

但是,在第二个代码块中,您只需将对同一对象的引用分配给另一个变量。然后清空列表,当然,这两个引用都可以看到。

第二部分:适当时返回内存,但并非总是如此。在 Python 的底层,有一个内存分配器可以控制内存的来源。有两种方式:通过brk()/sbrk()机制(用于较小的内存块)和通过mmap()(较大的块)。

在这里,我们有相当小的块,它们直接在数据段的末尾分配:

datadatadata object1object1 object2object2

如果我们只释放 object1,我们就会有一个内存间隙,可以为下一个对象重用,但不能轻易释放并返回给操作系统。

如果我们释放两个对象,内存可能会被返回。但是可能有一个将内存保留一段时间的阈值,因为立即返回所有内容并不是最好的事情。

于 2012-06-26T09:18:04.363 回答