python3.6下调试内存溢出问题

问题描述:

我分批读取的一批训练样本,原则上来说在读取下一个批次的数据时,上一个批次不应该依然占据内存。但实际运行时还是出现了内存溢出的情况,所以针对此问题单独进行分析。

分析python3.6的内存释放机制

理论部分

网上找到的python内存释放基本都是类似于智能指针,若出现变量对应的指针计数为0则清楚其内存。具体可以参考:PYTHON内存释放详解

实验一: python3.6使用numpy验证内存释放

计算机当前内存使用 1.8GiB
运行

a = np.arange(10**8 ,dtype = np.int32)

10 * 8 * 4 = 0.4GiB,当前计算机内存 2.2GiB [正常]

a = 1

由于array数据指针丢失,其内存会释放,当前计算机内存1.8GiB[正常]

命令理论内存消耗GiB实际内存消耗GiB
a = np.arange(10**8 ,dtype = np.int32)0.40.4
a.astype(np.int64)0.81.2
del a00.8

分析:在做astype时直接重新开辟了一块新的空间即使没有完全的指向,即使当做完del a 释放变量a后,此空间依然存在。
初始化了一块内存,即使未赋给变量此空间依然会被占用

实验二:将内存申请释放置函数中观察其释放

>>> def test():
...     a = np.arange(10**8 ,dtype = np.int32)
...     return a
>>> a = test()
>>> b = test()
>>> del a
>>> del b 

内存使用变化 0.4 - > 0.8 -> 0.4 -> 0[正常]

>>> def test():
...     a = np.arange(10**8 ,dtype = np.int32)
...     a.astype(np.int64)
...     return a
... 
>>> a = test()
>>> b = test()
>>> del a 
>>> del b

0.4-> 0.8 ->0.4 ->0 正常

分析:若给定新开辟的空间一个作用域,超过其作用域仍未被引用则会自动释放。

解决办法

强制垃圾回收

import gc
gc.collect()

续一个由于joblib引起的问题

def load_small_imdb(cur_ban):
    cur_ban = (cur_ban + 1) % ban_num
    fid = open(os.path.join(base_path,"smaill.imdb"),'rb')
    print("read...")
    train_data = pickle.load(fid)
    fid.close()
    print("finist...")
    random.shuffle(train_data)
    print("shuffle")
    tmp_list = np.array(train_data)
    a = tmp_list[:,0].tolist()
    b = np.copy(a)  #如果不进行copy会出现pickle的实际未释放的情况
    share_rate = np.copy(tmp_list[:,1])
    return b,share_rate,cur_ban

注意这里使用了copy,之所以使用copy是因为如果不拷贝,其array中的数据会依赖于pickle开启的空间,导致空间申请的过大。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值