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

以下代码充满了我的全部记忆:


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']


杨魅力
浏览 305回答 3
3回答

SMILET

如果需要,Python会从OS分配内存。如果不再需要它,它可能会也可能不会再次返回。但是,如果不返回,则内存将在后续分配中重用。您应该检查一下;但据推测,内存消耗不会增加更多。关于您的内存消耗估算:正如azorius所写,您的temp数组消耗16 MB,而您的A数组消耗约200 * 8 = 1600字节(出于内部原因,另加40)。如果采用100个字节,则为164000字节(加上一些用于列表)。除此之外,我没有任何关于您的内存消耗的解释。

慕虎7371278

我认为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
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python