【问题标题】:Python os.walk memory issuePython os.walk 内存问题
【发布时间】:2014-08-19 21:11:25
【问题描述】:

我编写了一个扫描仪,它在被扫描的系统的所有硬盘驱动器上查找某些文件。其中一些系统相当陈旧,运行 Windows 2000,内存为 256 或 512 MB,但文件系统结构很复杂,因为其中一些用作文件服务器。

我在脚本中使用 os.walk() 来解析所有目录和文件。

不幸的是,我们注意到扫描程序在扫描一段时间后会消耗大量 RAM,并且在遍历文件系统 2 小时后,我们发现仅 os.walk 函数就使用了大约 50 MB 的 RAM。这种 RAM 使用量会随着时间的推移而增加。扫描 4 小时后,我们有大约 90 MB 的 RAM。

有没有办法避免这种行为?我们还尝试了“betterwalk.walk()”和“scandir.walk()”。结果是一样的。 我们是否必须编写自己的 walk 函数从内存中删除已扫描的目录和文件对象,以便垃圾收集器可以不时删除它们?

谢谢

【问题讨论】:

  • 我知道os.path.isdir 存在内存泄漏,在os.walk 实现中使用你可以在post 上了解它,据我所知它已在python 3 中修复,请参阅泄漏报告here
  • 一种解决方法是使用 unicode 路径。
  • Python 版本 2.7.4 包含该修复程序,因此升级您的 Python 版本也应该有所帮助。
  • 我使用的是 2.7.7 版本,它仍然是我描述它的方式。也许这不是同一个问题?我将尝试使用 unicode 表示。
  • 你能在 Linux、OSX 上重现它吗?

标签: python memory os.walk


【解决方案1】:

你尝试过 glob 模块吗?

import os, glob

def globit(srchDir):
    srchDir = os.path.join(srchDir, "*")
    for file in glob.glob(srchDir):
        print file
        globit(file)

if __name__ == '__main__':
    dir = r'C:\working'
    globit(dir)

【讨论】:

  • 如果你把它变成一个发电机会更好。
【解决方案2】:

如果您在os.walk 循环中运行,del() 将是您不再需要的所有内容。并尝试在 os.walk 的每次迭代结束时运行 gc.collect()

【讨论】:

    【解决方案3】:

    生成器是更好的解决方案,因为它们进行惰性计算 这是一个实现示例。

    import os
    import fnmatch
    
    #this may or may not be implemented
    def list_dir(path):
        for name in os.listdir(path):
            yield os.path.join(path, name)
    
    #modify this to take some pattern as input 
    def os_walker(top):
        for root,dlist,flist in os.walk(top):
            for name in fnmatch.filter(flist, '*.py'):
                yield os.path.join(root, name)
    
    all_dirs = list_dir("D:\\tuts\\pycharm")
    
    for l in all_dirs:
        for name in os_walker(l):
            print(name)
    

    感谢David Beazley

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-05
      • 2012-09-13
      • 1970-01-01
      • 2014-11-19
      • 1970-01-01
      • 2016-07-17
      • 2017-09-10
      • 1970-01-01
      相关资源
      最近更新 更多