我有大量的代码,使用一些自定义类和许多字典。许多类将字典作为属性添加。我发现它占用了太多内存,尤其是当我循环时——即使我手动删除一些类和dict。在
我担心的是,字典被删除了,但是它们所包含的对象仍然存在。为了更好地管理内存,我需要重构代码,但是作为一个快速的解决方案,我希望能够递归地、积极地删除字典。如何实现这一目标?在
这里有一个例子。。。在
def get_lrg():
return {1: np.zeros((1000,1000,100))}
class H():
def add_lrg(self):
fd = get_lrg()
self.lrg = fd
for cls in ['a', 'b', 'c', 'd']:
exec('{0} = H()'.format(cls) )
exec('{0}.add_lrg()'.format(cls) )
del a
del b
del c
del d
另外,在Ipython中玩这个游戏:
^{pr2}$python的应用程序和应用程序。。。即使在字典“F”被删除之后(例如没有对对象的引用),它似乎也不会“释放”内存。我在我的机器上发现结果是不可预测的。有时内存确实会被刷新,而有时它似乎仍在使用中。在
如果字典中的对象在你去掉字典之后仍然存在,那么它们应该是活的,因为有些代码引用了它们。在
Python有两种处理内存的方法:
删除词典时,您将删除对相关对象的引用。如果这是对这些对象的最后一次引用,它们将自动为您释放。在
但是,如果对象之间存在循环,那么引用计数是不够的,因为这将导致循环中的所有对象至少有一个活动引用,即使不存在外部引用。在
这就是为什么还有一个垃圾回收器来清理这些垃圾,尽管时间稍晚一些。引用计数在引用达到0时处理对象,垃圾回收器稍后开始工作。在
因此,不需要递归地删除任何内容,只需删除对字典的引用,让Python担心其余的事情。在
这里还有另一个问题,以便提供更详细的信息:Why does python use both reference counting and mark-and-sweep for gc?。在
您可以使用以下代码进行验证:
这将向您展示
__del__
方法是作为del x
语句的一部分执行的。在然后你有了这个:
^{pr2}$这将向您展示周期(两个
x
和y
相互引用)的处理方式是不同的。在然后是这样的,我将
x
存储到字典中,然后删除字典,x
对象与字典一起被删除:当您删除一个对象时,您只是删除了对该对象的引用。如果该对象的引用计数降至0,则从内存中删除该对象对其他对象的引用。在
例如,字典不包含任何对象。它们包含的所有内容都是对其他对象的引用。如果你删除了对字典的所有引用,它会被自动清理、删除,并且它的所有引用也会消失。字典引用的任何键或值的引用计数都将减少1;如果该计数降至0,则这些键或值将被清除。在
因此,不需要递归地删除任何内容。如果对象不再被引用,它们将被自动清理。在
请注意,即使Python释放对象,进程内存的使用情况也不一定是而不是。除非一个进程需要重新分配内存以减少内存的使用量,否则可能需要一个内存重新分配给某个进程。在
相关问题 更多 >
编程相关推荐