【问题标题】:Optimize Memory Usage in Python: del obj or gc.collect()?优化 Python 中的内存使用:del obj 或 gc.collect()?
【发布时间】:2014-06-02 12:24:39
【问题描述】:

我有一个 python 脚本来分析日志文件中的用户行为。

这个脚本使用file.readlines()从几个大文件(每个大约50 GB)中读取,然后逐行分析它们并将结果保存在python对象的dict中,分析完所有行之后,dict被写入磁盘。

由于我有一个 64 核和 96 GB 内存的服务器,我启动了这个脚本的 10 个进程,每个进程都处理部分数据。此外,为了节省花费在 IO 操作上的时间,我使用 file.readlines(MAX_READ_LIMIT) 代替 file.readline() 并设置 MAX_READ_LIMIT = 1 GB。

在服务器上运行此脚本并使用 top 命令显示任务资源后,我发现虽然我的脚本的每个进程将只占用大约 3.5 GB 内存(总共 40 GB),但在服务器上只剩下 380 MB服务器(服务器上没有同时运行其他显着消耗内存的应用程序)。

所以,我想知道内存在哪里?应该还有大约 96-40=36GB 内存?

如果我在上述观察中犯了一些错误,请告诉我。

一个假设是未使用的内存不会立即放回内存池,所以我想知道如何立即明确地释放未使用的内存

我从python文档中了解到,python中管理内存有两种互补的方法:垃圾收集和引用计数,根据python doc:

由于收集器补充了已经使用的引用计数 Python,如果您确定您的程序,您可以禁用收集器 不会创建引用循环。

那么,我应该使用哪一个来处理我的案例,del obj 还是 gc.collect()?

【问题讨论】:

标签: python memory garbage-collection


【解决方案1】:

使用 file.readlines() ,然后逐行分析数据

这是一个糟糕的设计。 readlines 读取整个文件并返回一个 Python 字符串列表。如果只需要逐行处理数据,那么不使用readlines就遍历文件:

with open(filename) as f:
    for line in f:
        # process line

这将大大减少您的程序所需的内存量。

【讨论】:

  • This 在 PyCon 上就 CPython 和 PyPy 中的垃圾收集器进行了一场精彩的演讲。
  • 由于我有一台内存非常大的机器,我认为file.readlines()会节省频繁IO操作所花费的时间,所以我使用readlines()而不是readline()
  • @ice_lin 不,真的,不要使用.readlines()。如果您按照这个答案所说的方式进行操作,I/O 仍将被缓冲。底层操作系统缓冲 I/O,C 库可能缓冲 I/O,Python 本身可能缓冲更多。我不确定这个参数对.readlines() 有什么作用,所以我担心你的程序会尝试一次读取所有数据,如果这会迫使操作系统开始交换,这将是一个痛苦 性能受到打击。真的,就像这个答案所说的那样做。对其进行基准测试并亲自查看。
  • 如果你按照这个答案的建议去做,Python 应该继续制作字符串,在处理中使用它们,然后释放它们。如果你使用.readlines(),Python 会生成一大堆字符串对象,并构建一个list 来包含所有这些对象。读取 1 GB 的数据并用它构建字符串对象会大大降低缓存的命中率,这也会严重影响性能。
  • @steveha 谢谢,我会按照建议尝试一下。
猜你喜欢
  • 1970-01-01
  • 2011-03-09
  • 2017-07-19
  • 1970-01-01
  • 2019-02-21
  • 2014-10-02
  • 2016-09-01
  • 1970-01-01
  • 2021-12-02
相关资源
最近更新 更多