Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在循环中使用numpy load时内存溢出_Python_Memory_Numpy_Overflow_Memory Leaks - Fatal编程技术网

Python 在循环中使用numpy load时内存溢出

Python 在循环中使用numpy load时内存溢出,python,memory,numpy,overflow,memory-leaks,Python,Memory,Numpy,Overflow,Memory Leaks,循环加载npz文件会导致内存溢出(取决于文件) 列表长度) 以下这些似乎都没有帮助 删除在文件中存储数据的变量 使用mmap 调用gc.collect()(垃圾收集) 以下代码应再现该现象: import numpy as np # generate a file for the demo X = np.random.randn(1000,1000) np.savez('tmp.npz',X=X) # here come the overflow: for i in xrange(1000

循环加载npz文件会导致内存溢出(取决于文件) 列表长度)

以下这些似乎都没有帮助

  • 删除在文件中存储数据的变量

  • 使用mmap

  • 调用gc.collect()(垃圾收集)

  • 以下代码应再现该现象:

    import numpy as np
    
    # generate a file for the demo
    X = np.random.randn(1000,1000)
    np.savez('tmp.npz',X=X)
    
    
    # here come the overflow:
    for i in xrange(1000000):
        data = np.load('tmp.npz')
        data.close()  # avoid the "too many files are open" error
    
    在我的实际应用程序中,循环在一个文件列表上,溢出超过24GB的RAM! 请注意,这是在Ubuntu11.10上尝试过的,并且适用于numpy和v 1.5.1以及1.6.0

    我已经在中提交了一份报告,但这可能会引起更广泛的兴趣,因此我也将其发布在这里(此外,我不确定这是否是一个bug,但可能是我糟糕的编程造成的)

    解决方案(由HYRY提供): 命令

    del data.f
    
    应该在命令之前

    data.close()
    

    有关更多信息和找到解决方案的方法,请阅读下面HYRY的善意回答

    我认为这是一个错误,也许我找到了解决方案:调用“del data.f”

    发现这种内存泄漏。您可以使用以下代码:

    import numpy as np
    import gc
    # here come the overflow:
    for i in xrange(10000):
        data = np.load('tmp.npz')
        data.close()  # avoid the "too many files are open" error
    
    d = dict()
    for o in gc.get_objects():
        name = type(o).__name__
        if name not in d:
            d[name] = 1
        else:
            d[name] += 1
    
    items = d.items()
    items.sort(key=lambda x:x[1])
    for key, value in items:
        print key, value
    
    测试程序完成后,我在gc.get_objects()中创建了一个dict和count对象。以下是输出:

    ...
    wrapper_descriptor 1382
    function 2330
    tuple 9117
    BagObj 10000
    NpzFile 10000
    list 20288
    dict 21001
    
    从结果中我们知道BagObj和NpzFile有问题。查找代码:

    class NpzFile(object):
        def __init__(self, fid, own_fid=False):
            ...
            self.zip = _zip
            self.f = BagObj(self)
            if own_fid:
                self.fid = fid
            else:
                self.fid = None
    
        def close(self):
            """
            Close the file.
    
            """
            if self.zip is not None:
                self.zip.close()
                self.zip = None
            if self.fid is not None:
                self.fid.close()
                self.fid = None
    
        def __del__(self):
            self.close()
    
    class BagObj(object):
        def __init__(self, obj):
            self._obj = obj
        def __getattribute__(self, key):
            try:
                return object.__getattribute__(self, '_obj')[key]
            except KeyError:
                raise AttributeError, key
    
    NpzFile具有del(),NpzFile.f是一个BagObj,而BagObj.\u obj是NpzFile,这是一个参考循环,将导致NpzFile和BagObj都无法收集。以下是Python文档中的一些解释:


    因此,为了打破引用周期,需要调用“del data.f”

    我发现的解决方案:(python==3.8和numpy==1.18.5)

    import gc#导入垃圾收集器接口
    对于范围(1000)内的i:
    数据=np.load('tmp.npy')
    #过程数据
    del数据
    gc.collect()
    
    你有实际问题吗,还是这只是一篇伪博客文章?@Talonmes我不知道什么是伪博客文章。我相信我已经很清楚地说明了这个问题。至于它对我的真正重要性?如果这个问题没有解决,这意味着我必须找到一个不那么优雅的解决方案(比如退出会话并在文件块上运行作业)。我有一个3562个文件的目录。这足以使24GB(我拥有的RAM总量)溢出。另一个包含4735个文件。这两种方法都不能像我在原始帖子中使用的那样使用load函数进行处理。我没有检查您提出的查找问题来源的方法(我会尝试),但解决方案(del data.f)似乎可以解决问题。非常感谢您提供的解决方案(这是一种解脱)和快速回复!好啊通读如何找到解决方案的说明。我必须承认它对我来说有点高级(查看gc并阅读代码)。不过,下次遇到类似问题时,我会先尝试一下。所以,再一次-非常感谢-结果比我预期的更有用!(正在学习调试方法;-)顺便说一句,你知道为什么NpzFile类会以循环引用的方式编码吗?这个错误现在已经修复了。
    class NpzFile(object):
        def __init__(self, fid, own_fid=False):
            ...
            self.zip = _zip
            self.f = BagObj(self)
            if own_fid:
                self.fid = fid
            else:
                self.fid = None
    
        def close(self):
            """
            Close the file.
    
            """
            if self.zip is not None:
                self.zip.close()
                self.zip = None
            if self.fid is not None:
                self.fid.close()
                self.fid = None
    
        def __del__(self):
            self.close()
    
    class BagObj(object):
        def __init__(self, obj):
            self._obj = obj
        def __getattribute__(self, key):
            try:
                return object.__getattribute__(self, '_obj')[key]
            except KeyError:
                raise AttributeError, key