【问题标题】:Memory leaks in classes of linked nodes链接节点类中的内存泄漏
【发布时间】:2015-01-16 15:50:15
【问题描述】:

我正在尝试重新实现(再一次...我知道...)python 中的一个简单网络,该网络由引用其他节点类(它们的子类)的节点类组成,我想知道如果我创建会发生什么递归网络(node1 -> node2 -> node3 -> node1)并意外丢失对任何节点的所有引用。

假设我有以下代码

class node():
    def __init__(self):
        self.children = []

    def append(self, child):
        self.children.append(child)

node1 = node()
node2 = node()

node1.append(node2)
node2.append(node1) # now the network is recursive

node1 = 0
# node1 is still referenced in node2.children so will not be deleted
node2 = 0

# now both node1 and node2 are not directly referenced by any variable
# but they are referenced by the two children instances

在最后一行代码之后,对 node1 和 node2 的所有引用都丢失了,但最初分配给节点的内存仍然包含对自己的引用。

node1和node2还会被销毁吗?

【问题讨论】:

    标签: python memory-leaks


    【解决方案1】:

    是的,这些对象将被垃圾回收。垃圾收集器将检测循环引用并将其中断,以便可以进行正常的引用计数清理。请参阅gc module

    如果您的 node 类实现了 __del__ 方法并且您使用的 Python 版本 会遇到问题。在 3.4 现在大多数情况下可以break circular references involving instances with __del__ methods

    来自object.__del__ documentation

    注意del x不直接调用x.__del__()——前者将x的引用计数减一,后者仅在x的引用时调用计数达到零。可能阻止对象的引用计数变为零的一些常见情况包括: 对象之间的循环引用(例如,双向链表或具有父子指针的树数据结构);对捕获异常的函数的堆栈帧上的对象的引用(存储在sys.exc_traceback 中的回溯使堆栈帧保持活动状态);或对堆栈帧上的对象的引用,该对象在交互模式下引发了未处理的异常(存储在sys.last_traceback 中的回溯使堆栈帧保持活动状态)。第一种情况只能通过明确打破循环来补救;后两种情况可以通过将None 存储在sys.exc_tracebacksys.last_traceback 中来解决。启用选项循环检测器(默认情况下启用)时会检测到垃圾的循环引用,但只有在不涉及 Python 级别的 __del__() 方法时才能清理。有关循环检测器如何处理__del__() 方法的更多信息,尤其是垃圾值的描述,请参阅gc 模块的文档。

    【讨论】:

      猜你喜欢
      • 2015-10-18
      • 1970-01-01
      • 2020-11-15
      • 2022-01-08
      • 2020-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-28
      相关资源
      最近更新 更多