2

以下代码填满了我的所有记忆:

from sys import getsizeof
import numpy

# from http://stackoverflow.com/a/2117379/272471
def getSize(array):
    return getsizeof(array) + len(array) * getsizeof(array[0])


class test():
    def __init__(self):
        pass
    def t(self):
        temp = numpy.zeros([200,100,100])
        A = numpy.zeros([200], dtype = numpy.float64)
        for i in range(200):
            A[i] = numpy.sum( temp[i].diagonal() ) 
        return A

a = test()
memory_usage("before")
c = [a.t() for i in range(100)]
del a
memory_usage("After")
print("Size of c:", float(getSize(c))/1000.0)

输出是:

('>', 'before', 'memory:', 20588, 'KiB  ')
('>', 'After', 'memory:', 1583456, 'KiB  ')
('Size of c:', 8.92)

如果 c 为 ~ 9 KiB,为什么我使用 ~1.5 GB 的内存?这是内存泄漏吗?(谢谢)

memory_usage功能已发布在 SO 上,为清楚起见,在此处报告:

def memory_usage(text = ''):
    """Memory usage of the current process in kilobytes."""
    status = None
    result = {'peak': 0, 'rss': 0}
    try:
        # This will only work on systems with a /proc file system
        # (like Linux).
        status = open('/proc/self/status')
        for line in status:
            parts = line.split()
            key = parts[0][2:-1].lower()
            if key in result:
                result[key] = int(parts[1])
    finally:
        if status is not None:
            status.close()
    print('>', text, 'memory:', result['rss'], 'KiB  ')
    return result['rss']
4

3 回答 3

6

问题是由 numpy 1.7.0 版本的对角线() 函数引起的。升级到 1.7.1 解决了这个问题!

该解决方案由 numpy 邮件列表的 Sebastian Berg 和 Charles Harris 提供。

于 2013-06-13T15:12:33.430 回答
1

如果需要,Python 会从操作系统分配内存。

如果它不再需要它,它可能会或可能不会再次返回它。

但如果它不返回它,内存将在后续分配中被重用。你应该检查一下;但据说内存消耗不会增加更多。

关于您对内存消耗的估计:正如 azorius 已经写的那样,您的temp数组消耗 16 MB,而您的A数组消耗大约 200 * 8 = 1600 字节(+ 40 出于内部原因)。如果您取其中的 100 个,则为 164000 个字节(加上列表中的一些)。

除此之外,我对您的内存消耗没有任何解释。

于 2013-06-13T10:56:42.923 回答
0

我不认为 sys.getsizeof 返回你所期望的

你的 numpy 向量 A 是 64 位(8 字节) - 所以它占用(至少)

8 * 200 * 100 * 100 * 100 / (2.0**30) = 1.5625 GB

所以至少你应该在 100 个数组上使用 1.5 GB,最后几百毫克是用于索引大型 numpy 数据和 100 个对象的所有整数

无论 numpy 数组有多大,似乎 sys.getsizeof 总是返回 80:

sys.getsizeof(np.zeros([200,1000,100])) # return 80
sys.getsizeof(np.zeros([20,100,10])) # return 80

在您的代码中,您删除了一个小型工厂对象,它的 t 方法返回巨大的 numpy 数组,您将这些巨大的数组存储在一个名为 c 的列表中。尝试删除 c,然后您应该重新获得大部分 RAM

于 2013-06-13T11:19:34.990 回答