使用类

时间:2017-04-12 18:53:53

标签: python memory-leaks weak-references

我正在使用需要跟踪回调函数/方法的Python类,并且此类的实例需要在其中一个提供回调方法的类中具有引用(在其他位置)。但是,由于对象的循环引用,这会导致内存泄漏。

这在代码中更容易解释:

import psutil
import numpy as np

process = psutil.Process()

def show_mem(title):
    mem = process.memory_info()
    print(title + ':')
    print('Real:    {0:.1f}Mb'.format(mem.rss / 1024**2))
    print('Virtual: {0:.1f}Mb'.format(mem.vms / 1024**2))
    print()

class CallbackTracker(object):

    def __init__(self):
        self.callbacks = []

    def add_callback(self, callback):
        self.callbacks.append(callback)


class TestClass(object):

    def __init__(self):
        self.array = np.random.random(100000000)
        self.ct = CallbackTracker()
        self.ct.add_callback(self.callback)

    def callback(self):
        pass

def run():
    t = TestClass()

show_mem('Before run()')

run()

show_mem('After run()')

运行时,返回:

Before run():
Real:    22.4Mb
Virtual: 2451.9Mb

After run():
Real:    785.4Mb
Virtual: 3214.8Mb

阵列就是让内存使用更加明显。如果我删除以下行:

        self.ct.add_callback(self.callback)

然后内存泄漏就消失了:

Before run():
Real:    22.3Mb
Virtual: 2451.9Mb

After run():
Real:    22.3Mb
Virtual: 2451.9Mb

避免这种情况的最佳方法是什么?我尝试使用弱引用,但问题是在实例化类之后,回调函数似乎立即被解除引用:

import numpy as np
from weakref import proxy


class CallbackTracker(object):

    def __init__(self):
        self.callbacks = []

    def remove_callback(self, pcallback):
        print('removing callback')
        self.callbacks.remove(pcallback)

    def add_callback(self, callback):
        self.callbacks.append(proxy(callback, self.remove_callback))


class TestClass(object):

    def __init__(self):
        self.array = np.random.random(100000000)
        self.ct = CallbackTracker()
        self.ct.add_callback(self.callback)

    def callback(self):
        pass

t = TestClass()
print('done with TestClass()')

给出:

removing callback
done with TestClass()

这是不好的,因为回调(在实际代码中)将不起作用。我不清楚为什么self.callback在脚本结束之前被取消引用。什么是我原来的问题的最佳解决方案,有没有办法解决弱反射解决方案?

0 个答案:

没有答案