我有一个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)
问题:
tweak_list
中创建的new_list
的生存期是多少?它会在出口被销毁,还是会被垃圾收集(在哪一点?)。对tweak_list
的重复调用是否会产生大量的小列表,这些小列表会在很长一段时间内挥之不去?你知道吗list
转换为tuple
以用作dict
键时是否有临时创建?你知道吗dict
设置为空会释放内存吗?你知道吗
new_lst
在函数存在且未返回时被清除。它的引用计数下降到0,并且可以被垃圾收集。在当前的cpython实现中,这种情况会立即发生。你知道吗如果它被返回,
new_lst
引用的值替换了lst
;lst
引用的列表看到它的引用计数下降了1,但是new_lst
最初引用的值仍然被另一个变量引用。tuple()
键是存储在dict
中的值,因此这不是临时的。除了该元组之外,不会创建其他对象。用新的dict替换旧的
cache
dict将使引用计数减少1。如果cache
是dict的唯一引用,它将被垃圾收集。然后,这将导致包含的所有元组键的引用计数减少1。如果没有其他引用,这些将被垃圾收集。请注意,当Python释放内存时,并不一定意味着操作系统会立即回收内存。大多数操作系统只会在需要内存做其他事情时才回收内存,而不是假定程序可能很快又需要部分或全部内存。
您可能希望将Heapy作为分析内存使用情况的一种方法。我认为PySizer在某些情况下也用于此,但我不熟悉它。ObjGraph也是一个很好的工具。你知道吗
相关问题 更多 >
编程相关推荐