我有一个python代码,内存消耗随着时间的推移而稳步增长。虽然有几个对象可以合法地增长很大,但我试图了解我观察到的内存占用是否是由于这些对象,还是只是我乱丢内存而没有得到适当处理的临时对象---作为最近从手动内存管理世界的转换,我想我只是不完全理解python运行时如何处理临时对象的一些非常基本的方面。
考虑一个大致具有这种一般结构的代码(省略不相关的细节):
def tweak_list(lst):
new_lst = copy.deepcopy(lst)
if numpy.random.rand() > 0.5:
new_lst[0] += 1 # in real code, the operation is a little more sensible :-)
return new_lst
else:
return lst
lst = [1, 2, 3]
cache = {}
# main loop
for step in xrange(some_large_number):
lst = tweak_list(lst) # <<-----(1)
# do something with lst here, cut out for clarity
cache[tuple(lst)] = 42 # <<-----(2)
if step%chunk_size == 0:
# dump the cache dict to a DB, free the memory (?)
cache = {} # <<-----(3)
问题:
new_list
中创建的tweak_list
的有效期是多少?它会在退出时被销毁,还是会被垃圾收集(此时?)。对tweak_list
的重复呼叫是否会在很长一段时间内产生大量的小名单? list
转换为tuple
以用作dict
密钥时是否有临时创建?dict
设置为空的会释放内存吗?答案 0 :(得分:4)
new_lst
被清除。它的引用计数降为0,可以进行垃圾回收。关于当前发生的cpython实现。
如果 返回,new_lst
引用的值将替换lst
; lst
引用的列表看到它的引用计数下降1,但new_lst
最初引用的值仍由另一个变量引用。
tuple()
键是存储在dict
中的值,因此不是临时值。除了该元组之外,不会创建额外的对象。
用新的替换旧cache
dict会将引用计数减少一。如果cache
是对dict的唯一引用,那么它将被垃圾收集。然后,这会导致所有包含的元组键的引用计数减1。如果没有其他任何东西引用那些将被垃圾收集。
请注意,当Python释放内存时,这并不一定意味着操作系统会立即回收它。大多数操作系统只会在需要其他内容时回收内存,而不是假设程序可能很快就需要部分或全部内存。
答案 1 :(得分:0)