为了账号安全,请及时绑定邮箱和手机立即绑定

这是内存泄漏吗?(python + numpy的)

这是内存泄漏吗?(python + numpy的)

杨魅力 2021-03-31 15:15:57
以下代码充满了我的全部记忆:from sys import getsizeofimport numpy# from http://stackoverflow.com/a/2117379/272471def 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 Aa = test()memory_usage("before")c = [a.t() for i in range(100)]del amemory_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']
查看完整描述

3 回答

?
SMILET

TA贡献1796条经验 获得超4个赞

如果需要,Python会从OS分配内存。

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

但是,如果不返回,则内存将在后续分配中重用。您应该检查一下;但据推测,内存消耗不会增加更多。

关于您的内存消耗估算:正如azorius所写,您的temp数组消耗16 MB,而您的A数组消耗约200 * 8 = 1600字节(出于内部原因,另加40)。如果采用100个字节,则为164000字节(加上一些用于列表)。

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


查看完整回答
反对 回复 2021-04-01
?
慕虎7371278

TA贡献1802条经验 获得超4个赞

我认为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

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


查看完整回答
反对 回复 2021-04-01
  • 3 回答
  • 0 关注
  • 303 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信