【问题标题】:Resetting a dictionary to empty dictionary doesnt releases the memory?将字典重置为空字典不会释放内存吗?
【发布时间】:2019-09-15 03:08:40
【问题描述】:

所以, 我有一本字典,我想每天刷一次

所以.. 类似

d = {}

def refresh():
    global d
    now = datetime.datetime.now()
    if now >= TIME_TO_REFRESH:
       d  = {}

当我查看内存配置文件时,内存随着d 的大小增长而增长,但是当它刷新时,我预计内存会下降。 问题是它确实......但在很大程度上不是。 我想知道是否还需要做其他事情来确保刷新字典的全部内容。 也许它已经发生了,但我无法找到一个好的资源来了解垃圾收集器在这种情况下是如何工作的?

【问题讨论】:

  • 我在某处读到,当您覆盖一个对象时,它会自动从内存中刷新。
  • 为什么global 声明中有下划线?
  • 只有在垃圾收集器决定何时运行以删除无法访问的内存引用时才会减少内存

标签: python


【解决方案1】:

在上面的示例中,您并没有真正重置该字典。您只需将新的空名称分配给现有名称。要重置它,您需要致电d.clear()。即使将其设置为 None 也只会改变绑定,而不是可变对象本身。

Python 解释器决定何时使用引用计数释放内存,这意味着它计算存在多少引用(指向实际内存结构的名称)。如果它下降到零,则不使用内存并且可以释放内存。因此,如果您的程序的其他部分持有引用内存,则无法释放。这是一个非常简单的陈述(请参阅下面的文章 I 链接以获得进一步的解释)。

执行上述策略的称为垃圾收集器的组件可能会出于各种原因决定延迟释放内存。您可以(但不需要)通过执行以下代码来强制它:

import gc
gc.collect()

您可以在这篇精彩的文章中找到更多关于 Python 垃圾收集工作原理的信息:https://rushter.com/blog/python-garbage-collector/

【讨论】:

  • 在这种情况下,您也不需要有global 语句,因为您没有分配给d
【解决方案2】:

我会考虑做d.clear()。重新分配会创建一个新字典,旧字典最终将被垃圾收集,但这只是在所有其他对它的引用都消失后。 .clear() 实际上会删除字典中的内容。 https://stackoverflow.com/a/369925/3990806

【讨论】:

  • 我认为这不会影响它,因为仍然可以引用它。话虽如此,我并不完全确定global 是如何影响这一切的。我不认为我曾经写过一个全局变量。我认为如果您执行a = {}, b = a, a = {} 之类的操作更重要。在这种情况下,b 仍然会查看原始对象,因此不会被垃圾收集。如果它是全球性的,我不确定这将如何工作。我想一旦你重新分配它,所有其他全局引用都会查看新对象。
  • 还想跟进另一个想法。您可以尝试执行from sys import getrefcount,然后在重新分配后执行print(getrefcount(d)) 以检查是否仍有对该对象的引用。
猜你喜欢
  • 1970-01-01
  • 2023-03-30
  • 1970-01-01
  • 2015-06-15
  • 1970-01-01
  • 2019-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多