【问题标题】:Python garbage collection occurent in variable reset [duplicate]变量重置中发生Python垃圾收集[重复]
【发布时间】:2014-06-03 20:28:17
【问题描述】:

在 python 中假设执行以下操作:

# var is a variable, ClassName is the name of a class

var = ClassName(<params...>) # instatiate class to var 
var = ClassName(<params...>) # reset variable to new instance

# or in loop

while 1:
    var = ClassName(<params...>)
    # use var ...

我的问题是,前一个实例什么时候被垃圾收集? 是在创建下一个实例之前还是之后发生?

【问题讨论】:

标签: python garbage-collection


【解决方案1】:

请记住(定期)garbage-collectionreference-counting 是两种不同的机制。在您的情况下,引用计数是相关的。

引用计数为零的对象会立即被释放(无需等待定期 gc 运行)。

[正如@delnan 所指出的,引用计数不是 Python 的官方“功能”,而是 CPython 的具体实现细节。尽管如此,还是值得了解]

在你的情况下,你得到两个并发的现有对象。这是事情发生的顺序:

a new object is created, and is referenced by name "var"
[you now have one existing object]
while True:
    a new object is created
    [you now have two existing objects]
    it is referenced by name "var" (refcount += 1)
    old object is no longer referenced by name "var" (refcount -= 1)
    old object's refcount is now 0, it gets deallocated
    [you now have one existing object]

如果您希望只存在一个并发对象,您可以添加 del var 作为循环的第一行。

【讨论】:

  • 很多人认为引用计数是一种垃圾收集,他们说得有道理。您当然可以区分,但是说一个是 GC 而另一个不是引入了不必要的二分法。另外:整个引用计数业务只是一个 CPython 实现细节,对所有事情都使用跟踪 GC 是同样有效的。从可达性的角度考虑同样容易(恕我直言,更普遍有用)——它也不会改变答案。
  • @delnan 对,我一般同意你的评论。但是,我确实认为在某些(不常见的?)情况下,了解哪种机制起作用会有所帮助。它可能不会改变“之前还是之后?”的答案。问题,但它将答案更改为更笼统的“有多少并发对象?”问题。如果没有引用计数,你可以得到很多,而使用 rc,你只能得到两个。
  • 是的,这是真的。但另一方面,任何功能都依赖 RC 知识(特别是,假设只有两个对象,例如为了简化资源管理)会使代码在其他实现和存在循环的情况下变得脆弱。它主要用于破解 CPython 或调试内存问题(当然,或者纯粹出于好奇),但对编程没有多大用处。
  • @delnan 我还编辑了一些措辞,使其更符合您的评论。
  • @delnan (再次重申,我一点也不反对你)当我读到这个问题时,它是关于更好地理解语言的内部结构(是否依赖它们是另一回事)。提供一个将细节抽象出来的答案对我来说就像错过了重点......
【解决方案2】:

之后。如果它以前发生过,然后新实例的创建因异常而失败,则该变量将处于某种奇怪的状态,未初始化或引用垃圾。假设一个更智能的 Python 实现可能会提前收集旧对象,如果它可以证明新对象的创建将起作用并且不再需要旧对象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-03
    • 2013-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多