Skip to main content
 首页 » 编程设计

python之如何删除 python 中引用对象的内存位置

2025年05月04日14虾米哥

我想删除所有指向一个内存位置的对象。如果我不知道他们的全名怎么办?

class Foo(object): 
    pass 
 
 
class Bar(object): 
    pass 
 
a = Foo() 
b = a 
c = Bar() 
c.a_ref = a 
c.b_ref = b 
 
for item in a, b, c.a_ref, c.b_ref: 
    print(id(item)) 
 
""" Out: 
140035270075472 
140035270075472 
140035270075472 
140035270075472 
""" 

更新:

好的。我想删除 link 或 port1.link 并且不用担心链接到它的所有其他端口(port2.link),它们也必须消失。

class LINK(object): 
    pass 
 
 
class PORT(object): 
 
    def __init__(self, link=None): 
        self.link = link 
 
    def __repr__(self): 
        return str(id(self.link)) 
 
link = LINK() 
 
port1 = PORT() 
port2 = PORT() 
port1.link = port2.link = link 
 
print(id(link), port1, port2) 
# (140586778512720, 140586778512720, 140586778512720) 
del link 
print(port1, port2) 
# (140586778512720, 140586778512720) 
# want: (None, None) ??? 

请您参考如下方法:

您不能在 Python 中显式释放内存。垃圾收集器负责为你做这件事。

您可以做的是保证清除所有对对象的引用。垃圾收集器与 epochs(如 e1、e2 和 e3)一起工作,并且只有 e3 中的对象才会在下一次迭代中被清理。

如果没有对对象的引用,对象只会从纪元 eX 到 eY(其中 Y > X)。所以你的对象从 e1 开始;如果你“清理”所有引用,在垃圾收集器的下一次迭代中,它们将被移动到 e2;在下一个中,它们将被移动到 e3,最后释放内存。

您可以更改调用垃圾收集器的周期,但我不建议这样做。或者您可以使用 gc.collect() 强制调用垃圾收集器但正如我所说,您的对象在被清理之前必须经过所有时期(这就是为什么调用 gc.collector() 对您不起作用)。澄清一下,一旦达到阈值(gc 跟踪的内存中的对象数),就会调用垃圾收集器。

如果您想在 Python 中诊断内存泄漏,您还可以使用 objgraph非常好的图书馆。它使用对象之间的所有链接和引用构建图形,并让您识别循环。当您认为所有引用都已清除时,循环是垃圾收集器不释放对象的主要原因。这里有一个很好的教程http://chase-seibert.github.io/blog/2013/08/03/diagnosing-memory-leaks-python.html