这个问题主要发生在我使用numpy.load加载多个大型数据的时候,原本计划是加载一个数据,然后从其中使用deepcopy取出一部分数据,再使用del函数去进行释放空间,再加载下一个数据。但是在实际使用当中,deepcopy并没有使新数据划出空间,反而使得取出来的数据与原数据指向同一内存空间。
a = np.load(“a.npy”) c=[] max_size=1000 len= len(a) perm_indices = np.random.permutation(len)[:(max_size)] for j in perm_indices: c.append(copy.deepcopy(a[j]))
这就导致我在加载数据的时候内存不断增长直至爆炸!
所以我进行了以下的测试,首先申请了一个长度为200w的数组a,然后再重新申请一个长度和数值与一模一样的数组b,再使用deepcopy函数给数组b附上数组a的值
import numpy as np
import os
import psutil
import gc
import copy
import sys
def listcopy(x):
a = len(x)
b = [i for i in range(a)]
for i in range(a):
b[i] = copy.deepcopy(x[i])
return b
print('A:%.2f MB' % (psutil.Process(os.getpid()).memory_info().rss / 1024 / 1024))
list1=[ i for i in range(2000000)]
print('B:%.2f MB' % (psutil.Process(os.getpid()).memory_info().rss / 1024 / 1024))
list2=listcopy(list1)
print('C:%.2f MB' % (psutil.Process(os.getpid()).memory_info().rss / 1024 / 1024))
del list1
gc.collect()
print('D:%.2f MB' % (psutil.Process(os.getpid()).memory_info().rss / 1024 / 1024))
他的输出如下:
A:38.52 MB B:116.77 MB C:131.18 MB D:115.87 MB
如果我将listcopy()部分代码注释掉
def listcopy(x):
a = len(x)
b = [i for i in range(a)]
#for i in range(a):
# b[i] = copy.deepcopy(x[i])
return b
这就表示b是完全新申请的空间与a无关,这时候输出是
A:38.40 MB B:115.70 MB C:193.09 MB D:116.06 MB
显然虽然值相同,但是比没有使用deepcopy所要占的内存要大一些,当然,我们还是要尝试一下直接使用deepcopy拷贝,也就是将list2=listcopy(list1)替换为list2=copy.deepcopy(list1)这时候输出为:
A:38.38 MB B:116.48 MB C:130.91 MB D:115.63 MB
和分部拷贝差不多,但是如果我们将listcopy()函数中的复制的长度减少,也就是如下改变:
def listcopy(x):
a = len(x)
b = [i for i in range(a)]
for i in range(int(a/2)):
b[i] = copy.deepcopy(x[i])
return b
他的输出将会是
A:38.51 MB B:115.75 MB C:163.00 MB D:116.72 MB
我们将会看到相较于没有进行拷贝和完全拷贝,这个内存占用大于完全拷贝,小于不进行拷贝。在之后测试之中我试过将复制长度再缩小一倍,这个内存占用还会曾大。这说明deepcopy虽然是深度拷贝,但是python似乎还是将一些值指向了同样的内存。这就导致释放原数据的时候并不能完全释放。
但是我还是找到了一个不算是解决方法的方法就是在拷贝的时候直接乘1,也就是将listcopy()修改如下:
def listcopy(x):
a = len(x)
b = [i for i in range(a)]
for i in range(a):
b[i] = x[i]*1
return b
这时候输出就正常了
A:38.26 MB B:115.80 MB C:192.86 MB D:115.85 MB



