栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

关于python deepcopy内存问题

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

关于python deepcopy内存问题

关于python deepcopy内存问题

这个问题主要发生在我使用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
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1025647.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号