Python单调增加内存使用量(泄漏?)

pio*_*otr 9 python memory-leaks

我正在使用这个简单的代码并观察单调增加的内存使用情况.我正在使用这个小模块将东西转储到磁盘上.我观察到它发生在unicode字符串而不是整数,是不是我做错了?

当我做:

>>> from utils.diskfifo import DiskFifo
>>> df=DiskFifo()
>>> for i in xrange(1000000000):
...     df.append(i)
Run Code Online (Sandbox Code Playgroud)

内存消耗稳定

但是当我这样做时:

>>> while True:
...     a={'key': u'value', 'key2': u'value2'}
...     df.append(a)
Run Code Online (Sandbox Code Playgroud)

它走到了屋顶.任何提示?在模块下面......


import tempfile
import cPickle

class DiskFifo:
    def __init__(self):
        self.fd = tempfile.TemporaryFile()
        self.wpos = 0
        self.rpos = 0
        self.pickler = cPickle.Pickler(self.fd)
        self.unpickler = cPickle.Unpickler(self.fd)
        self.size = 0

    def __len__(self):
        return self.size

    def extend(self, sequence):
        map(self.append, sequence)

    def append(self, x):
        self.fd.seek(self.wpos)
        self.pickler.dump(x)
        self.wpos = self.fd.tell()
        self.size = self.size + 1

    def next(self):
        try:
            self.fd.seek(self.rpos)
            x = self.unpickler.load()
            self.rpos = self.fd.tell()
            return x

        except EOFError:
            raise StopIteration

    def __iter__(self):
        self.rpos = 0
        return self
Run Code Online (Sandbox Code Playgroud)

com*_*ave 14

pickler模块存储它在备忘录中看到的所有对象,因此它不必两次腌制相同的东西.您想跳过此(因此对您的对象的引用不会存储在您的pickler对象中)并在转储之前清除备忘录:

def append(self, x):
    self.fd.seek(self.wpos)
    self.pickler.clear_memo()
    self.pickler.dump(x)
    self.wpos = self.fd.tell()
    self.size = self.size + 1
Run Code Online (Sandbox Code Playgroud)

资料来源:http://docs.python.org/library/pickle.html#pickle.Pickler.clear_memo

编辑:您可以通过使用以下追加功能来腌制对象时实际观察备忘录的大小:

def append(self, x):
    self.fd.seek(self.wpos)
    print len(self.pickler.memo)
    self.pickler.dump(x)
    self.wpos = self.fd.tell()
    self.size = self.size + 1
Run Code Online (Sandbox Code Playgroud)