【问题标题】:How to delete objects to increase free memory in python?如何删除对象以增加python中的可用内存?
【发布时间】:2018-08-21 19:43:05
【问题描述】:

我的 python 应用程序在启动期间从文件中读取数据并将这些数据存储在字典中(字典是数据读取器类的属性)。一旦应用程序启动并使用了读取的数据,就不再需要字典中的这些数据。但是,它们会消耗大量内存。如何删除这些字典以释放内存?

例如:

class DataReader():
    def __init__(self, data_file):
        self.data_file = data_file

    def read_data_file_and_store_data_in_dictionary():
        self.data_dictionary = {}
        for [data_name, data] in self.data_file:
             self.data_dictionary[data_name] = data

class Application():
    def __init__(self, data_file):
        self.data_reader = DataReader()
        self.data_reader.read()

    def start_app(self):
        self.use_read_data()

应用程序启动后,不再需要self.data_dictionary。如何永久删除self.data_dictionary

【问题讨论】:

  • 当不再需要时,只需发送self.data_reader = None
  • @martineau 真的有用吗? del 不需要吗?
  • 是的,它确实有效,所以del 不是必需的。 Python中的对象是引用计数的,当它达到零值时会自动删除。

标签: python memory-management


【解决方案1】:

使用 Python,您不应该关心内存管理。

Python 有一个出色的garbage collector,它为每个对象计算代码中的引用。
如果没有引用,则该对象将被取消分配。

在您的情况下,如果在您使用完内存后内存没有空闲,则意味着该对象仍然可以在您的程序中使用。如果你删除它然后尝试调用它,你会得到一个ReferenceError

其他答案中有人建议使用del,但它只会删除变量名。

我的建议是确保您的代码不再实际调用该对象,如果确实如此,请相应地操作您的数据(使用lightweight db,将它们保存在本地硬盘驱动器上,...)并在何时检索它们需要。如果你的大字典是一个仍在使用的类的类参数,但不再需要字典,你应该把这些字典放在类之外(也许引用一个只管理字典的新类)。在this Q&A 中,您将找到优化内存使用的有用提示。

您可以阅读this article 来深入了解 Python 的垃圾收集器

【讨论】:

  • python的垃圾收集器会自动运行吗?它如何知道何时删除不必要的对象?
  • 我也同意这个答案。虽然del 会做你想做的事,但还有更好的方法。
【解决方案2】:

使用del 语句

del self.data_dictionary  # or del obj.data_dictionary

注意,这只会删除对字典的引用。如果字典的任何其他引用仍然存在(例如,如果您已经完成 d = data_reader.data_dictionaryd 仍然引用 data_dictionary),那么字典将不会从内存中释放。这也包括对d.keys(), d.values(), d.items() 的任何引用。

只有当所有的引用都被删除后,字典才会最终被释放。

【讨论】:

  • 删除self.data_reader会释放内存吗?它会删除所有内容(字典、键、值等)吗?
  • 是的,前提是您不持有对其中任何一个的引用
  • 有没有办法知道对python项目中对象的所有引用?高级python程序员如何处理?
  • 他们没有。最好的方法是永远不要引用太大而无法处理的东西。改用惰性迭代器之类的东西。事实上,这正是您的 self.data_file 对象的内容——内置对象已经以减少内存的方式制作。
  • 最后一个问题:使用del后,需要gc.collect()释放内存吗?
【解决方案3】:

将数据放在更小的范围内怎么样?

class Application():
    def __init__(self, data_file):
        self.use_read_data(DataReader(data_file).read())

应用启动后,不再需要self.data_dictionary

如果您在应用程序的整个生命周期都不需要数据,那么您不应该将其存储在实例属性中。

选择正确的范围,您将无需担心删除变量。

【讨论】:

  • 用这种方法,DataReader不会和Application一样活下去吗?
  • @alwbtc 没有引用的对象已准备好进行垃圾回收。然后会发生什么取决于实施。 CPython 将在中间释放它。
【解决方案4】:

del 将删除对该对象的引用,但它仍可能在内存中。在这种情况下,垃圾收集器 (gc.collect([generation])) 将释放内存:

https://docs.python.org/2.7/library/gc.html

import gc

[...]
# Delete reference
del object
# Garbage collector
gc.collect()
[...]

【讨论】:

  • 这不起作用:obj1 = dict; obj2 = obj1; del obj1; gc.collect()obj2 仍然存在,引用同一个对象。顺便说一句,有趣的建议是强制垃圾收集器在特定时刻进行收集
猜你喜欢
  • 2017-11-07
  • 2016-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-26
相关资源
最近更新 更多