我在用python 2.7编写的python脚本中使用字典。
当我使用 pympler 运行我的脚本来查找内存泄漏时,我发现列表对象的大小正在不断增加。
这些列表包含这些词典的键。这些列表是python词典的构建实现吗?
pympler的输出如下:
types | # objects | total size
============================ | =========== | ============
list | 99221 | 106.53 MB
str | 105530 | 6.06 MB
dict | 602 | 940.48 KB
code | 1918 | 239.75 KB
int | 10043 | 235.38 KB
wrapper_descriptor | 1120 | 87.50 KB
type | 87 | 76.80 KB
builtin_function_or_method | 719 | 50.55 KB
method_descriptor | 601 | 42.26 KB
set | 132 | 33.41 KB
weakref | 372 | 31.97 KB
tuple | 364 | 26.24 KB
<class 'abc.ABCMeta | 20 | 17.66 KB
member_descriptor | 233 | 16.38 KB
function (__init__) | 114 | 13.36 KB
列表的大小正在增加,scipt的RES内存也在增加? 该列表包含所使用的字典的键,我认为它是字典的内部实现。 密钥是否作为列表存储在内存中?如何管理内存泄漏?
以下是上述输出的代码:
from pympler import tracker
from pympler import summary
from pympler import muppy
import types
while(1):
d={}
for i in range(1000,1100):
d[i]=1
for i in range(1000,1050):
del d[i]
all_objects = muppy.get_objects()
sum1 = summary.summarize(all_objects)
summary.print_(sum1)
type = muppy.filter(all_objects, Type=types.ListType)
print 'length :%s'%(len(type))
答案 0 :(得分:4)
你的问题是一个很难测试的东西。
在你的循环中,你这样做:
all_objects = muppy.get_objects()
您永远不会删除all_objects
,因此在您拨打get_objects
时,所有对象的上一个列表仍然是实时对象。当然,当您将新列表分配给all_objects
时,您会删除该引用,但为时已晚;现在,所有对象的新列表都引用了所有对象的旧列表。
这实际上是人们使用各种进程内存调试工具的常见问题 - 很容易最终保留工具的工件并最终调试这些工件。
确保您不会意外地执行此类操作的一个好方法是将您的muppy代码分解为函数:
def summarize():
all_objects = muppy.get_objects()
sum1 = summary.summarize(all_objects)
summary.print_(sum1)
type = muppy.filter(all_objects, Type=types.ListType)
print 'length :%s'%(len(type))
现在,在循环中,您只需致电summarize()
,并确保您无法找到任何您不想要的局部变量。