递归删除python字典
我有大量的代码,使用了一些自定义类和很多字典。许多类将字典添加为属性。我发现它占用了太多内存,尤其是在循环时——即使我手动删除了一些类和dict 我担心的是,词典正在被删除,但它们包含的对象仍然存在。我需要重构代码以实现更好的内存管理,但作为一个快速解决方案,我希望能够递归地、主动地删除字典。这将如何实现 这里有一个例子递归删除python字典,python,dictionary,Python,Dictionary,我有大量的代码,使用了一些自定义类和很多字典。许多类将字典添加为属性。我发现它占用了太多内存,尤其是在循环时——即使我手动删除了一些类和dict 我担心的是,词典正在被删除,但它们包含的对象仍然存在。我需要重构代码以实现更好的内存管理,但作为一个快速解决方案,我希望能够递归地、主动地删除字典。这将如何实现 这里有一个例子 def get_lrg(): return {1: np.zeros((1000,1000,100))} class H(): def add_lrg(sel
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中玩一玩:
fd = get_lrg()
fd2 = get_lrg()
F = {1: fd, 2: fd2}
F = {}
F = {1: fd, 2: fd2}
del F[1]
del F
并观察python应用程序的内存使用情况。。。即使在删除字典“F”之后,它也不会“释放”内存(例如,没有对对象的引用)。我在我的机器上发现结果是不可预测的。有时内存看起来确实被刷新了,但有时它似乎仍在使用。删除对象时,您只是删除了对该对象的引用。如果该对象的引用计数下降到0,则该对象将从内存中删除,并带走该对象对其他对象的所有引用 例如,字典不包含任何对象。它们包含的全部内容都是对其他对象的引用。如果删除对字典的所有引用,它将自动清理、删除,并且它的所有引用也将消失。字典引用的任何键或值的引用计数将下降1;反过来,如果计数下降到0,它们将被清除 因此,不需要递归删除任何内容。如果对象不再被引用,它们将自动清理
请注意,即使Python释放对象,也不一定会占用进程内存。操作系统能够并且确实将内存分配给进程,以减少内存流失;进程可能需要再次增加内存使用量,除非其他地方迫切需要内存,否则分配将保留一段时间。如果在您清除字典后字典中的对象仍然存在,那么它们应该存在,因为某些代码引用了它们 Python有两种处理内存的方法:
class X:
def __del__(this):
print("deleted")
def __init__(this):
print("constructed")
print("before")
x = X()
print("after")
del x
print("done")
这将向您显示\uuu del\uu
方法作为del x
语句的一部分执行
那么你有这个:
class X:
def __del__(this):
print("deleted")
def __init__(this):
print("constructed")
print("before")
x = X()
y = X()
x.y = y
y.x = x
print("after")
del x
del y
print("done")
这将向您显示循环(x和y都相互引用)的处理方式不同
然后你有了这个,我将x
存储到字典中,然后删除字典,x
对象与字典一起被删除:
class X:
def __del__(this):
print("deleted")
def __init__(this):
print("constructed")
print("before")
d = {"x": X()}
print("after")
del d
print("done")
你在找这样的东西吗:?相关:我添加了一些细节来说明我在说什么,但与此同时,还有一些进一步的讨论…@John:不要把内存分配和内存使用混为一谈。操作系统可以自由地将内存分配给进程,即使它们不再需要内存。因此,可能是延迟导致了我的问题。问题是我不能确定(毫无疑问,由于一些糟糕的代码)所有引用都被删除了……这是一个不同的问题,毫无疑问,这是您需要解决的问题,但这并不是因为Python没有清理保留在字典中的对象。如果他们不想死,就必须有别的东西让他们活着。在第二个/中间代码示例中,我试图激发垃圾收集器来处理我的对象,但它没有。毫无疑问,它会在一段时间后处理好它,但我并没有费心去弄清楚它需要多长时间或者如何激怒它。