为什么在这种情况下没有释放内存?

Why is memory not freed in this case?

我有以下 Python 代码:

import os, psutil
import numpy as np
process = psutil.Process(os.getpid())
print(process.memory_info().rss)

def append(x):
    x.append(np.random.normal(size=(1000,1000)))

a = []
append(a)
append(a)
append(a)
print(process.memory_info().rss)
a = [i[:10] for i in a]
print(process.memory_info().rss) # memory has not been reclaimed!!

我想知道为什么 Python 当我把所有的数组都做成一个更小的数组时,为什么不使用更少的内存。

经过测试,似乎根本原因正是@juanpa 所怀疑的。

numpy 中的基本索引 returns a view 而不是数组的副本,因此仍保留底层缓冲区。您可以使用 a[0].base.

访问原始数组

但是,如果您像这样创建数组的副本:a = [i.copy() for i in a],您会突然发现分配的内存减少,因为原始对象将全部丢失并被清除。

但是请注意,如果您在切片和复制之间分配其他对象,由于 fragmentation.

,您可能不会释放该内存

运行这段代码,你会看到不同之处:

import os, psutil
import numpy as np
process = psutil.Process(os.getpid())
print(process.memory_info().rss)

def append(x):
    x.append(np.random.normal(size=(1000,1000)))

a = []
append(a)
append(a)
append(a)
print(process.memory_info().rss)
a = [i[:10].copy() for i in a]   # Copy the array.
print(process.memory_info().rss)