Python字典是否在重新分配时释放了所有内存?

时间:2011-07-18 19:26:56

标签: python

使用Python。我有一个函数,它从队列中读取并根据从队列中读取的记录中的一些XML标记创建一个字典,并返回该字典。我将这个函数永远地称为循环。每次都会重新分配字典。字典以前使用的内存是否在每次重新分配时被释放,或者它是否会被孤立并最终导致内存问题?

def readq():
    qtags = {}
    # Omitted code to read the queue record, get XML string, DOMify it

    qtags['result'] = "Success"
    qtags['call_offer_time'] = get_node_value_by_name(audio_dom, 'call_offer_time')
    # More omitted code to extract the rest of the tags

    return qtags

while signals.sigterm_caught == False:
    tags = readq()
    if tags['result'] == "Empty":
        time.sleep(SLEEP_TIME)
        continue
    # Do stuff with the tags

因此,当我每次在该循环中重新分配标记时,先前赋值所使用的内存是否会在被新赋值分配之前被释放?

3 个答案:

答案 0 :(得分:8)

如果可以证明对象的内存(根据语言实现在运行时的知识)可以不再访问它并且垃圾收集器认为它适合创建集合,则将释放该对象的内存。这是绝对最低限度,你不应再假设了。而且你通常不应该不得不担心

更实际地说,它可以在最后一个引用之间的某个时间点释放(其中“引用”不限于范围中的名称,但可以是使对象成为的任何内容{ {3}})被删除并且内存耗尽。它不必由运行代码的Python实现释放,它也可以将内存清理留给操作系统并忘记任何终结器等。请注意,最后一个引用死亡和实际丢弃的内存使用之间可能会有明显的延迟。但是如前所述,如果有垃圾要收集,大多数实现都会尽量避免过多的内存使用。

更实际的是,你可以在CPython(参考实现)上运行它,它总是使用并且最可能总是使用引用计数(用真实的GC来增加处理循环引用),所以除非有循环引用(相对罕见,你的代码看起来不像它有它们,但可以发生在例如图形结构中)它将在删除/覆盖它的最后一个引用时立即释放。当然,其他实现并不是那么可预测 - 仅PyPy就有六个不同的垃圾收集器,只有一个属于上一段。

答案 1 :(得分:2)

不,它将在创建新对象后释放。

为了使引用计数降低旧对象,必须将tags指向新对象。在readq返回后会发生这种情况,因此至少两个对象都会从qtags = {}开始到tags = readq()之后存在。

正如@delnan所说,在tags指向新对象后不久,旧的对象将被垃圾收集器释放,因为不再有对它的引用。

答案 2 :(得分:1)

通常Python可以跟上你扔的任何东西。 Python中使用的垃圾收集器使用引用计数,因此您的内存使用量应该是常量,您将看不到内存中的任何峰值。当您删除引用(将变量分配给其他内容)时,如果您愿意,垃圾收集器会将内存返回到“堆”中。所以不要担心记忆。我已经运行模拟器进行数小时重写变量的测试,但内存使用率保持不变。当您为其分配新词典时,它将被释放。