最近处理数据,有一个地方用的字典储存的,不知道为啥,有个地方的内存占用看不懂啊:
这是第一种:
31 83.4 MiB 0.0 MiB @profile 32 def main(): 33 # data_count = taskResultDB.getResult(21, taskResultDB.resultType.FRQ_COUNT) 34 # data_sum = taskResultDB.getResult(21, taskResultDB.resultType.FRQ_SUM) 35 # data_tfidf = taskResultDB.getResult(21, taskResultDB.resultType.TFIDF) 36 # data_tfidf_2 = taskResultDB.getResult(21, taskResultDB.resultType.TFIDF_2) 37 83.4 MiB 0.0 MiB data = taskResultDB.getResult(21) 38 39 ''' 40 data_count = taskResultDB.tranDataToDict( 41 data_count)[taskResultDB.resultType.FRQ_COUNT] 42 data_sum = taskResultDB.tranDataToDict( 43 data_sum)[taskResultDB.resultType.FRQ_SUM] 44 data_tfidf = taskResultDB.tranDataToDict( 45 data_tfidf)[taskResultDB.resultType.TFIDF] 46 data_tfidf_2 = taskResultDB.tranDataToDict( 47 data_tfidf_2)[taskResultDB.resultType.TFIDF_2] 48 ''' 49 1778.2 MiB 1694.8 MiB datas = taskResultDB.tranDataToDict(data) 50 51 # wordDict = tranToWordDict(data_sum, data_count) 52 1874.5 MiB 96.3 MiB wordDict = tranToWordDict_2(datas) 53 54 # data_count = None 55 # data_sum = None 56 # data_tfidf = None 57 # data_tfidf_2 = None 58 1850.5 MiB -24.0 MiB datas = None 59 1552.3 MiB -298.2 MiB data = None 60 1551.8 MiB -0.5 MiB gc.collect() 61 1551.8 MiB 0.0 MiB return wordDict
第二种就是将注释去掉,注释掉现在的代码
Line # Mem usage Increment Line COntents================================================ 31 83.4 MiB 0.0 MiB @profile 32 def main(): 33 83.4 MiB 0.0 MiB data_count = taskResultDB.getResult(21, taskResultDB.resultType.FRQ_COUNT) 34 83.4 MiB 0.0 MiB data_sum = taskResultDB.getResult(21, taskResultDB.resultType.FRQ_SUM) 35 83.4 MiB 0.0 MiB data_tfidf = taskResultDB.getResult(21, taskResultDB.resultType.TFIDF) 36 83.4 MiB 0.0 MiB data_tfidf_2 = taskResultDB.getResult(21, taskResultDB.resultType.TFIDF_2) 37 38 83.4 MiB 0.0 MiB data_count = taskResultDB.tranDataToDict( 39 463.8 MiB 380.3 MiB data_count)[taskResultDB.resultType.FRQ_COUNT] 40 463.8 MiB 0.0 MiB data_sum = taskResultDB.tranDataToDict( 41 560.4 MiB 96.7 MiB data_sum)[taskResultDB.resultType.FRQ_SUM] 42 560.4 MiB 0.0 MiB data_tfidf = taskResultDB.tranDataToDict( 43 659.5 MiB 99.1 MiB data_tfidf)[taskResultDB.resultType.TFIDF] 44 659.5 MiB 0.0 MiB data_tfidf_2 = taskResultDB.tranDataToDict( 45 697.5 MiB 38.0 MiB data_tfidf_2)[taskResultDB.resultType.TFIDF_2] 46 47 713.1 MiB 15.6 MiB wordDict = tranToWordDict(data_sum, data_count) 48 49 712.6 MiB -0.5 MiB data_count = None 50 700.6 MiB -12.0 MiB data_sum = None 51 699.1 MiB -1.5 MiB data_tfidf = None 52 590.9 MiB -108.2 MiB data_tfidf_2 = None 53 546.9 MiB -44.0 MiB gc.collect() 54 546.9 MiB 0.0 MiB return wordDict
data 是获取的一个 ORM 对象,获取数据的 数据是 4 部分,sun,count,tfidf,tfidf_2,转存出的 dict 的结构是:
{ type:{ "word": data } } type 只有下面的四种...
就是一个嵌套字典,只不过第二个是分开转换的. 可以理解为 data_count + data_sum + data_tfidf + data_tfidf_2 = data 但是根据信息能看出,输出的 data 字典占用的空间远远大于前几个的和,这是为什么呢
哦,还有一个信息就是 count,sum,tfidf,tfidf_2 的内容除了 value 不一样以外,key 是一样的,和这个有关系么?
python 用的我好想用 C++重写......几十万条瞬间一个 G 没了.....前段时间后台程序自己关了,连 log 里都没有信息,就像断点一样.....盯着消失才知道是内存消耗没了....
![]() | 1 fcicq 2016-05-28 00:04:48 +08:00 ![]() dict 的动态类型支持不是无代价的所以本来就不省内存. key 压缩肯定也不会有. 用数据库的话说你建了四个表存了 4 份 key. |
2 yangtukun1412 2016-05-28 09:28:11 +08:00 ![]() 应该是 tranDataToDict() 方法内部使用了大量内存 + gc 的锅 |
3 yangyaofei OP @fcicq @yangtukun1412 昨天一个原因一个原因找,发现不是字典的锅,是我用的数据库 orm peewee 的问题,我一次让他插入所有的表,估计是生成什么巨大的表达式了,我改成一次插入 3000 个表就好了……… |
4 yangyaofei OP |
5 yangyaofei OP |
6 yangyaofei OP @yangtukun1412 我说错了, tran 函数确实占用了很大内存,但是是必要的。我说的是第一个 tran 是分开的而后面的是合并一起的,输出的数据是一样多的,但是后一个却占用比前一个高很多很多…… |
7 yangtukun1412 2016-05-28 16:34:10 +08:00 @yangyaofei 当使用了大量内存时, Python 的 gc 不会立即释放这部分内存,而是会尝试复用. 最简单的测试方法, 你可以试一下函数中 range(1000000) 和 4 次 range(250000) 的内存消耗. |