【问题标题】:How to release memory handled by numpy如何释放 numpy 处理的内存
【发布时间】:2017-05-03 05:18:45
【问题描述】:
# 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')

内存在 normalize_feature_step3 和 normalize_feature_step4 之间没有任何变化。最终内存为98M。

所以我认为 numpy 可能会处理一些内存。我想知道如何释放内存。 谢谢!

【问题讨论】:

    标签: python numpy memory


    【解决方案1】:

    调用gc.collect() 并不意味着内存会被回收。它只是告诉gc回收,做不做是自己决定的,所以不能直接让gc回收。这不是 numpy 的问题,而是每个有 gc 的语言的普遍问题。

    【讨论】:

    • 调用 gc.collect() 是什么意思?
    • 我知道。谢谢
    【解决方案2】:

    只是你犯的一个小错误:

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

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

    因此,当您在将a 添加到列表后执行del a 时,您并没有释放a 的内存,您只是从a 中删除了命名引用。也就是说,名为 a 的变量将不复存在,但其内容仍将存在于内存中,由 b[0] 指出。

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

    例如,当您对 numpy 数组进行简单添加时,会即时创建相同大小的临时数组来存储中间值,从而消耗比可能需要更多的内存。

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

    【讨论】:

      猜你喜欢
      • 2012-07-20
      • 1970-01-01
      • 2015-05-31
      • 2021-01-11
      • 2013-07-02
      • 1970-01-01
      • 1970-01-01
      • 2014-03-21
      • 2012-02-19
      相关资源
      最近更新 更多