如何释放numpy处理的内存

时间:2017-05-03 05:18:45

标签: python numpy memory

# encoding: utf-8

import sys
import commands
import time
import gc

import numpy

process=sys.argv[0]

def get_use_memory():
    global process
    return commands.getstatusoutput('ps aux | grep "{0}" | grep -v "grep"'.format(process))

def normalize_feature(node, delete_list):
    print 'normalize_feature_step1', get_use_memory()
    normal_features = []
    for i in range(0, node.shape[0]):
        feature_numpy = node[i, :]

        feature_numpy_d = numpy.delete(feature_numpy, delete_list, axis=0)
        normal_features.append(feature_numpy_d)
        del feature_numpy
        del feature_numpy_d

    print 'normalize_feature_step2', get_use_memory()
    np_normal_features = numpy.array(normal_features)
    print sys.getsizeof(np_normal_features) / float(1024) / float(1024)
    print 'normalize_feature_step3', get_use_memory()
    del normal_features
    gc.collect()
    print 'normalize_feature_step4', get_use_memory()
    return np_normal_features

#gc.set_debug(gc.DEBUG_STATS|gc.DEBUG_LEAK)

rows=1024
columns=10240
a = []
for i in range(0, rows):
    b = []
    for j in range(0, columns):
        b.append(float(i) * j)
    a.append(b)
    del b

print get_use_memory()

node_1 = numpy.array(a)
print sys.getsizeof(node_1) / float(1024) / float(1024)
print get_use_memory()
del a
gc.collect()
print get_use_memory()

node_2 = normalize_feature(node_1, [0, 100, 1000])
print sys.getsizeof(node_2) / float(1024) / float(1024)
print get_use_memory()

del node_1
del node_2
gc.collect()
print get_use_memory()

输出:

(0, 'wangye    5319 96.5  1.0 581036 360528 pts/28  S+   11:23   0:03 python test.py')
80.0001068115
(0, 'wangye    5319  106  1.3 662964 442456 pts/28  S+   11:23   0:04 python test.py')
(0, 'wangye    5319  112  0.2 316812 98072 pts/28   S+   11:23   0:04 python test.py')
normalize_feature_step1 (0, 'wangye    5319  112  0.2 316812 98072 pts/28   S+   11:23   0:04 python test.py')
normalize_feature_step2 (0, 'wangye    5319  115  0.5 398372 179704 pts/28  S+   11:23   0:04 python test.py')
79.9766693115
normalize_feature_step3 (0, 'wangye    5319  116  0.7 480272 261596 pts/28  S+   11:23   0:04 python test.py')
normalize_feature_step4 (0, 'wangye    5319  116  0.5 398688 180148 pts/28  S+   11:23   0:04 python test.py')
79.9766693115
(0, 'wangye    5319  116  0.5 398688 180148 pts/28  S+   11:23   0:04 python test.py')
(0, 'wangye    5319  117  0.0 234864 16324 pts/28   S+   11:23   0:04 python test.py')

在normalize_feature_step3和normalize_feature_step4之间释放80M内存。因为del normal_features释放了numpy.ndarray的项目。而最终的记忆只有16M。

但是当我更改代码的第38行和第39行时: 行= 10240 列= 1024

输出:

(0, 'wangye    5400 99.5  1.1 604944 385888 pts/28  S+   11:25   0:03 python test.py')
80.0001068115
(0, 'wangye    5400  109  1.4 686872 467892 pts/28  S+   11:25   0:04 python test.py')
(0, 'wangye    5400  116  0.2 317024 98176 pts/28   S+   11:25   0:04 python test.py')
normalize_feature_step1 (0, 'wangye    5400  116  0.2 317024 98176 pts/28   S+   11:25   0:04 python test.py')
normalize_feature_step2 (0, 'wangye    5400  100  0.5 399592 180852 pts/28  S+   11:25   0:05 python test.py')
79.7657318115
normalize_feature_step3 (0, 'wangye    5400  101  0.8 481276 262576 pts/28  S+   11:25   0:05 python test.py')
normalize_feature_step4 (0, 'wangye    5400  101  0.7 480444 261904 pts/28  S+   11:25   0:05 python test.py')
79.7657318115
(0, 'wangye    5400  101  0.7 480444 261904 pts/28  S+   11:25   0:05 python test.py')
(0, 'wangye    5400  101  0.2 316836 98296 pts/28   S+   11:25   0:05 python test.py')

memoryize_feature_step3和normalize_feature_step4之间的内存没有任何变化。最后的记忆是98M。

所以我想也许numpy处理一些记忆。我想知道如何释放内存。 谢谢!

2 个答案:

答案 0 :(得分:0)

呼叫gc.collect()并不意味着内存将被回收。它只是告诉gc回收,是否自行决定,所以你不能直接让gc回收。这不是关于numpy的问题,但是对于每个拥有gc的语言都是一个普遍的问题。

答案 1 :(得分:0)

你正在犯的一个快速错误:

>>> a = (1, 2, 3, 4, 5)
>>> b = []
>>> b.append(a)
>>> b[0] is a
True

向列表添加元素不会复制该元素,它只是将指向该元素的指针添加到列表中(is关键字检查身份匹配)。

因此,在将del a添加到列表后执行a时,您没有释放a的内存,只是从a中删除了命名参考。这是名称为a的变量将不复存在,但其内容仍将存在于内存中,由b[0]指向。

简而言之,python中的del语句不等同于C / C ++中的free。如果您关注内存,则根本不应该使用python,或者您应该对代码更加谨慎,但依赖del不是一种选择。 del不应用于这些目的。

例如,当你简单地添加numpy数组时,会动态创建相同大小的临时数组来存储中间值,从而消耗更多的内存而不是可能需要的内存。

这个,numpy和一般的python是用于快速原型设计的语言/库。如果您需要完全控制所使用的资源,则应该回退到C / C ++(或其他编译语言)。任何解释的语言都会自动释放内存,然后存储停止被指向,但它不是即时的,你不能依赖它。