【问题标题】:File stays in memory after being closed文件关闭后留在内存中
【发布时间】:2020-10-12 02:44:36
【问题描述】:

我想在 Kaggle 上使用 Jupyter Notebook 循环处理许多 mp3 文件。然而,以二进制形式读取 mp3 文件似乎会将文件保留在内存中,即使在函数返回并且文件已正确关闭之后也是如此。这会导致内存使用量随着每个文件的处理而增长。问题似乎出在read() 函数中,因为pass 不会导致任何内存使用量增长。

在循环播放 mp3 文件时,内存使用量的增长等于正在处理的文件的大小,这表明文件保存在内存中。

函数返回后如何读取文件而不将其保存在内存中?

def read_mp3_as_bin(fname):
    with open(fname, "rb") as f:
        data = f.read() # when using 'pass' memory usage doesn't grow
    print(f.closed)
    return

for fname in file_names: # file_names are 25K paths to the mp3 files
    read_mp3_as_bin(fname)

“解决方案”

我确实在本地运行了这段代码,并且根本没有内存使用量增长。因此,看起来 Kaggle 确实以不同的方式处理文件,因为这是该测试中唯一的变量。我会尝试找出为什么这段代码在 Kaggle 上的行为不同,当我知道更多时会告诉你。

【问题讨论】:

  • 您如何验证文件是否保留在内存中?
  • 你能告诉我们你怎么知道文件还在内存中吗?函数结束后,data 无法保存在内存中。
  • 我添加了一些额外的信息,内存使用增长等于正在处理的文件的大小,这表明文件正在保存在内存中。

标签: python file memory


【解决方案1】:

我很确定您测量的内存使用错误。

我创建了 3 个 50MB 的 dummy 文件并在它们上运行您的代码,输出每次循环迭代的函数内外的内存使用情况,结果与文件关闭后释放的内存一致。

为了测量内存使用情况,我使用了here 建议的解决方案,而要创建虚拟文件,我只是按照this blog post 的建议运行truncate -s 50M test_1.txt

看看:

import os
import psutil


def read_mp3_as_bin(fname):
    with open(fname, "rb") as f:
        data = f.read()  # when using 'pass' memory usage doesn't grow
    if data:
        print("read data")

    process = psutil.Process(os.getpid())
    print(f"inside the function, it is using {process.memory_info().rss / 1024 / 1024} MB")  # in Megabytes
    return


file_names = ['test_1.txt', 'test_2.txt', 'test_3.txt']

for fname in file_names:  # file_names are 25K paths to the mp3 files
    read_mp3_as_bin(fname)
    process = psutil.Process(os.getpid())
    print(f"outside the function, it is using {process.memory_info().rss / 1024 / 1024} MB")  # in Megabytes

输出:

read data
inside the function, it is using 61.77734375 MB
outside the function, it is using 11.91015625 MB
read data
inside the function, it is using 61.6640625 MB
outside the function, it is using 11.9140625 MB
read data
inside the function, it is using 61.66796875 MB
outside the function, it is using 11.91796875 MB

【讨论】:

  • 有趣的是,我尝试运行我自己的代码来处理较小的文件大小(5MB、10MB、20MB 和 30MB),但有时在return 上没有释放内存的奇怪行为。也许有一些奇怪的缓存正在进行,其上限为少量内存使用。也就是说,它似乎不会无限期地泄漏,当使用 5 个文件进行测试时,只有 2 个文件没有被释放。对于 40MB 以上的文件,内存总是在 return 上释放。
  • 深入挖掘,无论文件大小如何(对于
猜你喜欢
  • 1970-01-01
  • 2016-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多