Warm tip: This article is reproduced from serverfault.com, please click

unix-python中的eval函数的高RAM使用率

(unix - high RAM usage by eval function in python)

发布于 2020-11-30 10:34:43

我将每个文件的第1行(不是第0行)实现为2个文件(第1个〜30MB和第2个〜50MB)中的字符串,其中第0行仅包含一些我不需要atm的信息。第1行是一个字符串数组,其中包含约1.3E6个较小的数组,例如['I1000009','A','4024','A']作为信息。

[[['I1000009', 'A', '4024', 'A'], ['I1000009', 'A', '6734', 'G'],...],[['H1000004', 'B', '4024', 'A'], ['L1000009', 'B', '6734', 'C'],...],[and so on],...]

两个文件都以相同的方式填充。这就是文件大小在30至50MB之间的原因。我使用.py脚本读取了这些文件,以便可以访问所需的单个信息:

import sys

myID        = sys.argv[1]
otherID     = sys.argv[2]

samePath        = '/home/srv/Dokumente/srv/' 
FolderName      = 'checkArrays/'
finishedFolder  = samePath+'finishedAnalysis/'
myNewFile       = samePath+FolderName+myID[0]+'/'+myID+'.txt'
otherFile       = samePath+FolderName+otherID[0]+'/'+otherID+'.txt'
nameFileOKarray = '_array_goodData.txt'

import csv 
import os 
import re #for regular expressions
# Text 2 - Start
import operator # zum sortieren der csv files
# Text 2 - End

whereIsMyArray    = 1
text_file         = open(finishedFolder+myID+nameFileOKarray, "r")
line              = text_file.readlines()[whereIsMyArray:];
myGoodFile        = eval(line[0])
text_file.close()

text_file         = open(finishedFolder+otherID+nameFileOKarray, "r")
line              = text_file.readlines()[whereIsMyArray:];
otherGoodFile     = eval(line[0])
text_file.close()

print(str(myGoodFile[0][0][0]))
print(str(otherGoodFile[0][0][0]))

问题是,如果我通过外壳启动.py脚本:

python3 checkarr_v1.py 44 39

我的4GB pi服务器的RAM增加到RAM和Swap死掉的极限。然后我尝试在32Gb RAM服务器上启动.py脚本,并查看它是否有效,但是RAM的使用量确实很大。看照片

(松弛模式)的RAM和CPU的正常使用的概述: slackmode

(startsequence)最高RAM〜6GB和CPU使用情况概述:最高点

然后它在大约1分钟后上升和下降:1.2 Gb至3.6 Gb,然后至1.7 Gb,然后至1 Gb,然后脚本完成了大约1分钟,并显示了正确的输出。

你能帮助我了解是否有更好的方法可以解决4Gb树莓派吗?这是写2个文件的更好方法,因为[“,]符号也占用了文件中的空格吗?这是一种更好的解决方案,因为eval函数是将字符串实现为数组吗?我不明白为什么80MB的文件将RAM增加到6Gb左右,这听起来我做错了。

Questioner
user2
Viewed
0
Mattias Nilsson 2020-11-30 22:07:56

如果你将1.3E9数组读到应用程序中,无论做什么,它都会有很多字节。

我不知道你的代码是否执行了你实际想要的操作,但是你只使用了第一个数据项。如果那是你要执行的操作,则不要阅读整个文件,只需阅读第一部分。

而且:我建议不要使用“ eval”对数据进行反序列化。内置的json模块将以几乎相同的格式提供数据(如果你控制输入格式)。

最后,如果你想在程序中保存那么多数据,那么你将需要使用大量GB的内存。

如果你只想处理它,那么我将采用一种更迭代的方法,一次做些事情,而不是吞下整个文件。特别是在资源有限的情况下。

更新:我现在看到的是1.3e6,而不是1.3e9条目。巨大差距。:-)然后json数据应该可以。在我的计算机上,1.3M的列表['RlFKUCUz', 'A', '4024', 'A']大约需要250MB。