这是内存泄漏吗? [英] Is this a memory leak?

查看:113
本文介绍了这是内存泄漏吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用gc模块来调试泄漏。

这是一个gui程序,我把这个函数连接到了一个按钮上。



我将set debug设置为 gc.SAVE_ALL

 > gc.collect()
>
>打印gc.garbage

这是输出


[(< type'_ctypes.Array'> ;,),{'__module__':'ctypes._endian','__dict__':< attribute' __weakref__':'c_int_Array_3'对象>,'_length_':3,'_type_'的<属性'__weakref__':< class'ctypes.c_int'> ;,'__doc__' :< c'int_Array_3>,< class'ctypes._endian.c_int_Array_3'>,'c_int_Array_3'对象>的属性'__dict__','c_int_Array_3'对象>的属性'__weakref__'。 _endian.c_int_Array_3'>,< type'_ctypes.Array'>,< type'_ctypes._CData>,< type'object'>',(< type'_ctypes.CFuncPtr'> ,','__module__':'ctypes','__dict__':'_FuncPtr'objects>的属性'__dict__','__weakref__':< _FuncPtr的属性'__weakref__'对象>,'_flags_':1,'__doc__':无,'_restype_':< class'ctypes.c_int'>},< class'ctypes._FuncPtr'>,<属性'__dict__' _FuncPtr'objects>,< _FuncPtr'objects>的属性'__weakref__',(< class'ctypes._FuncPtr'> ;,< type'_ctypes.CFuncPtr'> ;,< type'_ctypes._CData>> < cell'at 0x10a24b0:0x10e6a50>的资源对象,< 0x10a2478的单元: ,< 0x10e2f30处的单元:0x826880处的NoneType对象>,0x10e2d70处的单元< 0x826880>处的无类型对象,0x10e2ef8处的单元:0x7f1703dd5e10处的str对象,< 0x10e2de0处的单元:0x118aaa0处的单元对象, 'Accept':'application / json','User-Agent':'couchdb-python 0.6'},(< 0x10e2f30的单元格:0x826880的NoneType对象>,< 0x10a24b0的单元格:0x10e6a50的资源对象& <位于0x10e2de0的单元:位于0x118aaa0的字典对象,<位于0x10a2478的单元:位于0x11a4440的字典对象>,位于0x10e2d70的单元:位于0x826880的NoneType对象,位于0x10e2ef8的单元:位于0x7f1703dd5e10的str对象, 0x7f1703949f68处的函数对象:0x10ec7d0处的函数对象),< 0x10ec7d0处的函数_make_request,(1,),{},< 0x10e2bb0处的单元:0x10e6a50处的资源对象>,0x10e2e88处的单元:0x119f360处的dict对象> ,< 0x10f0130处的单元:0x10ec578处的函数对象>,0x10f01d8处的单元:0x826880处的NoneType对象,< 0x10f01a0处的单元:0x826880>处的None类型对象,< 0x10f00f8处的单元,> 0x7f170b05d810& ; 0x10f00c0处的单元格:0x11969a0处的词典对象,{'Accept':'application / json','User-Agent':'couchdb-python 0.6'},(< 0x10f01d8处的单元格:0x826880& ; 0x10e2bb0处的单元格:0x10e6a50处的资源对象>,0x10f00c0处的单元格:0x11969a0处的对象对象,< 0x10e2e88处的单元格:在0x119f360>处的对象,< 0x10f01a0处的单元:0x826880处的NoneType对象,>,0x10f00f8处的单元,0x7f170b05d810处的str对象,< 0x10f0130处的单元:0x10ec578处的功能对象>),< function_make_request at 0x10ec578> ,(1,),{},< 0x10f0440处的单元:0x10e6a50处的资源对象>,0x10f02b8处的单元:0x11b2d70处的dict对象,0x10f0360处的单元:0x10ec6e0处的函数对象,< 0x10f0280处的单元:0x826880>处的NoneType对象,< 0x10f02f0处的单元:0x10ca228处的str对象,> 0x10f0408处的单元:0x7f170b05d810处的str对象,< 0x10f0050处的单元:0x11b6370>处的字典对象,{'Accept':'application / json','User-Agent':'couchdb-python 0.6'},(< cell at 0x10f0280:NoneType object at 0x826880>]


gc.garbage列表包含很多项目。这是否意味着gc.garbage中的对象正在泄漏或已被收集或将被收集?

文档


gc.garbage



收集器发现无法释放但无法释放的对象列表(不可收集的对象)。


所以它看起来像是某种泄漏给我的。现在文档继续解释可能出现这种情况的条件:


具有 del 方法,并且是引用循环的一部分,导致整个引用循环无法收集,包括不一定在循环中但只能从循环中访问的对象。 Python不会自动收集这些循环,因为一般来说,Python无法猜测运行 del ()方法的安全顺序。如果您知道安全订单,则可以通过检查垃圾列表来强制解决问题,并明确打破由于列表中的对象而导致的周期。请注意,这些对象由于处于垃圾列表中而保持活动状态,因此它们也应该从垃圾中移除。例如,打破循环之后,请执行del gc.garbage [:]以清空列表。通过不使用 del ()方法创建包含对象的循环来避免此问题通常会更好,并且在这种情况下可以检查垃圾以验证是否未创建这样的循环。


现在设置 DEBUG_SAVEALL 标志会使所有的垃圾泄漏。来自同一来源:


gc.DEBUG_SAVEALL



设置时,所有不可达找到的对象将被追加到垃圾中,而不是被释放。这对于调试泄漏程序非常有用。


所以,是的,那个列表是泄漏内存。但你告诉它泄漏所有这些!


I'm using gc module to debug a leak.

It's a gui program and I've hooked this function to a button.

I've set set debug more to gc.SAVE_ALL

> gc.collect()
> 
> print gc.garbage

and this is the output

[(<type '_ctypes.Array'>,), {'__module__': 'ctypes._endian', '__dict__': <attribute '__dict__' of 'c_int_Array_3' objects>, '__weakref__': <attribute '__weakref__' of 'c_int_Array_3' objects>, '_length_': 3, '_type_': <class 'ctypes.c_int'>, '__doc__': None}, <class 'ctypes._endian.c_int_Array_3'>, <attribute '__dict__' of 'c_int_Array_3' objects>, <attribute '__weakref__' of 'c_int_Array_3' objects>, (<class 'ctypes._endian.c_int_Array_3'>, <type '_ctypes.Array'>, <type '_ctypes._CData'>, <type 'object'>), (<type '_ctypes.CFuncPtr'>,), {'__module__': 'ctypes', '__dict__': <attribute '__dict__' of '_FuncPtr' objects>, '__weakref__': <attribute '__weakref__' of '_FuncPtr' objects>, '_flags_': 1, '__doc__': None, '_restype_': <class 'ctypes.c_int'>}, <class 'ctypes._FuncPtr'>, <attribute '__dict__' of '_FuncPtr' objects>, <attribute '__weakref__' of '_FuncPtr' objects>, (<class 'ctypes._FuncPtr'>, <type '_ctypes.CFuncPtr'>, <type '_ctypes._CData'>, <type 'object'>), {}, <cell at 0x10a24b0: Resource object at 0x10e6a50>, <cell at 0x10a2478: dict object at 0x11a4440>, <cell at 0x7f1703949f68: function object at 0x10ec7d0>, <cell at 0x10e2f30: NoneType object at 0x826880>, <cell at 0x10e2d70: NoneType object at 0x826880>, <cell at 0x10e2ef8: str object at 0x7f1703dd5e10>, <cell at 0x10e2de0: dict object at 0x118aaa0>, {'Accept': 'application/json', 'User-Agent': 'couchdb-python 0.6'}, (<cell at 0x10e2f30: NoneType object at 0x826880>, <cell at 0x10a24b0: Resource object at 0x10e6a50>, <cell at 0x10e2de0: dict object at 0x118aaa0>, <cell at 0x10a2478: dict object at 0x11a4440>, <cell at 0x10e2d70: NoneType object at 0x826880>, <cell at 0x10e2ef8: str object at 0x7f1703dd5e10>, <cell at 0x7f1703949f68: function object at 0x10ec7d0>), <function _make_request at 0x10ec7d0>, (1,), {}, <cell at 0x10e2bb0: Resource object at 0x10e6a50>, <cell at 0x10e2e88: dict object at 0x119f360>, <cell at 0x10f0130: function object at 0x10ec578>, <cell at 0x10f01d8: NoneType object at 0x826880>, <cell at 0x10f01a0: NoneType object at 0x826880>, <cell at 0x10f00f8: str object at 0x7f170b05d810>, <cell at 0x10f00c0: dict object at 0x11969a0>, {'Accept': 'application/json', 'User-Agent': 'couchdb-python 0.6'}, (<cell at 0x10f01d8: NoneType object at 0x826880>, <cell at 0x10e2bb0: Resource object at 0x10e6a50>, <cell at 0x10f00c0: dict object at 0x11969a0>, <cell at 0x10e2e88: dict object at 0x119f360>, <cell at 0x10f01a0: NoneType object at 0x826880>, <cell at 0x10f00f8: str object at 0x7f170b05d810>, <cell at 0x10f0130: function object at 0x10ec578>), <function _make_request at 0x10ec578>, (1,), {}, <cell at 0x10f0440: Resource object at 0x10e6a50>, <cell at 0x10f02b8: dict object at 0x11b2d70>, <cell at 0x10f0360: function object at 0x10ec6e0>, <cell at 0x10f0280: NoneType object at 0x826880>, <cell at 0x10f02f0: str object at 0x10ca228>, <cell at 0x10f0408: str object at 0x7f170b05d810>, <cell at 0x10f0050: dict object at 0x11b6370>, {'Accept': 'application/json', 'User-Agent': 'couchdb-python 0.6'}, (<cell at 0x10f0280: NoneType object at 0x826880>]

The gc.garbage list has a lot of items. Does this mean the objects in gc.garbage are leaking or have been collected or will be collected?

解决方案

From the docs:

gc.garbage

A list of objects which the collector found to be unreachable but could not be freed (uncollectable objects).

So it looks like some kind of leak to me. Now the docs go on to explain the conditions under which this could occur:

Objects that have del() methods and are part of a reference cycle cause the entire reference cycle to be uncollectable, including objects not necessarily in the cycle but reachable only from it. Python doesn’t collect such cycles automatically because, in general, it isn’t possible for Python to guess a safe order in which to run the del() methods. If you know a safe order, you can force the issue by examining the garbage list, and explicitly breaking cycles due to your objects within the list. Note that these objects are kept alive even so by virtue of being in the garbage list, so they should be removed from garbage too. For example, after breaking cycles, do del gc.garbage[:] to empty the list. It’s generally better to avoid the issue by not creating cycles containing objects with del() methods, and garbage can be examined in that case to verify that no such cycles are being created.

Now having the DEBUG_SAVEALL flag set makes all of your garbage leak. From the same source:

gc.DEBUG_SAVEALL

When set, all unreachable objects found will be appended to garbage rather than being freed. This can be useful for debugging a leaking program.

So, again, yes, that list is leaked memory. But you told it to leak all that!

这篇关于这是内存泄漏吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆