【问题标题】:Cannot free a numpy array无法释放 numpy 数组
【发布时间】:2020-07-16 19:58:53
【问题描述】:

我正在尝试消除程序中的内存瓶颈。这是有趣的部分:

print_mem_info()
print("creating array")
arr = np.empty(vol_to_write.get_shape(), dtype=np.float16)
for v_tmp, a_tmp in zip(v_list, a_list):
    s = to_basis(v_tmp, vol_to_write).get_slices()
    arr[s[0][0]:s[0][1],s[1][0]:s[1][1],s[2][0]:s[2][1]] = copy.deepcopy(a_tmp)
print_mem_info()
print("deleting array")
del arr
print_mem_info()

这是输出:

Used RAM:  4217.71875 MB
creating array
Used RAM:  4229.68359375 MB
deleting array
Used RAM:  4229.2890625 MB

对于 print_mem_info,我只是使用 psutil 库:

def print_mem_info():
    mem = psutil.virtual_memory()
    swap = psutil.swap_memory()
    used_ram = (mem.total - mem.available) /1024 /1024
    used_swap = swap.used /1024 /1024 
    print("Used RAM: ", used_ram, "MB")
    # print("Used swap: ", used_swap, "MB")

我只是创建一个 numpy 数组,填充它,然后我想删除它(在程序中我应该稍后删除它,但出于调试目的,我将 del 放在这里)。 我无法理解的是为什么 del 没有从 RAM 中删除数组,因为没有任何其他对该数组的引用。我尝试使用 gc.collect(),但它什么也没做。

我从 stackoverflow 阅读了很多其他帖子,但我无法弄清楚。我知道不应该使用 gc.collect() 并且我在某处读到不推荐使用 del 但我正在操作非常大的 numpy 数组,所以我不能只让它们进入 RAM。


[编辑]:

我尝试在这里创建一个最小的示例:

import numpy as np
import psutil, os

def print_mem_info():
    process = psutil.Process(os.getpid())
    print(process.memory_info().vms // 1024 // 1024)

if __name__ == "__main__":
    print("program starts")
    print_mem_info()

    print("creating samples...")
    a_list = list()
    for i in range(4):
        a_list.append(np.random.rand(100,100,100))
    print_mem_info()

    print("creating array...")
    arr = np.empty((400,100,100))
    print_mem_info()

    print("filling the array...")
    for i, a_tmp in enumerate(a_list):
        arr[i*100:(i+1)*100,:,:] = a_tmp
        del a_tmp
    print_mem_info()

    print("deleting the array...")
    del arr
    print_mem_info()

【问题讨论】:

  • 可惜比那个复杂,这是我做研究论文的一个实验,我一个接一个地运行几个脚本,需要配置文件路径,克隆一些我的项目等......对不起,我希望我能
  • 我的错是“psutil”我把代码放在问题中(psutil.readthedocs.io/en/latest
  • 首先,del 不会删除对象。 del arr 取消绑定 arr 变量。其次,释放对象并不一定会将内存返回给操作系统。
  • 有问题。在一个空程序中,我的机器上使用了 11 GB。除了 print_mem_info() 没有任何代码。您正在获取系统范围的信息,但您应该查看程序范围的信息
  • @ThomasWeller 你确定你根本没有使用任何内存吗?这很奇怪......对我来说它似乎有效,我的意思是如果我不运行任何其他东西,psutil 告诉我的内存消耗与 htop 相同。

标签: python arrays numpy


【解决方案1】:

您是在系统级别而不是进程级别测量内存。您不知道您机器上的所有其他进程都在做什么。

注意measuring memory of a process 的示例代码。很多例子都是混合虚拟内存和物理内存。

RSS(linux 术语)和 Working Set(Windows 术语)不适合讨论您的问题,因为它们只考虑当前位于物理 RAM 中的那部分内存。由于这在很大程度上取决于您拥有多少物理 RAM,因此这在机器之间会有所不同,并且绝对不可比较。

VMS(Linux 术语)或 Private Bytes(Windows 术语)更可靠,因为它们还会考虑已使用的内存,但如果您没有足够的物理 RAM,则会交换到磁盘。

以下代码应该可以帮助您开始:

import numpy as np
import psutil
import os

def print_mem_info():
    process = psutil.Process(os.getpid())
    print(process.memory_info().vms // 1024 // 1024)

print_mem_info()
arr = np.empty((100000,100000))
print_mem_info()
del arr
print_mem_info()

在我的机器上打印

261
76705
262

对于 8 字节数组中的 100.000 * 100.000 个项目来说,76 GB 听起来是合理的。

使用RSS,效果不可见:

47
47
47

【讨论】:

  • 感谢您提供这些信息,这很有趣,我现在将使用它来监控我的程序。不幸的是,我仍然看不到我的数组已被删除(我认为从 a_tmp 复制数据存在问题)
猜你喜欢
  • 1970-01-01
  • 2018-10-21
  • 1970-01-01
  • 2016-05-20
  • 2015-06-17
  • 1970-01-01
  • 2019-10-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多