我有一个25Gb的纯文本文件,大约有1000万行,每行有几百个字。每条线都需要单独处理,我试图将块拆分为十几个并行处理的工人。目前一次加载一百万行(由于某种原因,它在RAM中占用~10Gb,即使它只在磁盘上解压缩为3Gb),将它分成12个方向,然后使用多处理将其映射到12个工作者.Pool。
问题是,当我的12名工作人员完成处理他们分配的数据时,他们的RAM没有被释放,并且在下一次百万行迭代中只增加了~10Gb。
我已经尝试了以前的数据,将以前的数据重置为空分配,然后使用eval(),gc.collect()创建可迭代的变量名称删除,并完全将IO分离到自己的功能,所有这些都没有运气和完全相同的问题。运行调试表明python解释器只识别预期的数据,并且无法访问上一次迭代的数据,为什么RAM实际上没有被释放?
下面的代码是我尝试分离所有环境的最新版本,而不是最有效但是" BigFileOnDisk"在SSD上,因此每次重复读取文件与实际处理数据相比可忽略不计。以前有过"阅读"分配功能中的功能,在工人完成后删除所有数据,结果相同。
def allocation():
fileCompleted = False
currentLine = 0
while not fileCompleted:
lineData, currentLine, fileCompleted = read(numLines=1000000, startLine=currentLine)
list_of_values(function_object=worker, inputs=lineData, workers=12)
def read(numLines, startLine=0):
currentLine = 0
lines = []
with open(BigFileOnDisk, 'r') as fid:
for line in fid:
if currentLine >= startLine:
lines.append(line)
if currentLine - startLine >= numLines:
return lines, counter, False
currentLine += 1
# or if we've hit the end of the file
return lines, counter, True
def worker(lines):
outputPath = *root* + str(datetime.datetime.now().time())
processedData = {}
for line in lines:
# process data
del lines
with open(outputPath, 'a') as fid:
for item in processedData:
fid.write(str(item) + ', ' + str(processedData[item]) + '\n')
def list_of_values(function_object, inputs, workers = 10):
inputs_split = []
subsection_start = 0
for n in range(workers):
start = int(subsection_start)
end = int(subsection_start + len(inputs) / workers)
subsection_start = end
inputs_split.append( inputs[start:end] )
p = Pool(workers)
p.map(function_object, inputs_split)
答案 0 :(得分:4)
您没有加入子流程。 list_of_values
创建的Pool
个完成的进程仍然活着之后(有点像僵尸,但有活着的父进程)。他们仍然拥有所有的价值观。您无法在main中看到他们的数据,因为它在另一个进程中(出于同样的原因gc.collect
无效)。
要释放工作人员分配的内存,您需要手动加入Pool
或使用with
。
def list_of_values(function_object, inputs, workers = 10):
inputs_split = []
subsection_start = 0
for n in range(workers):
start = int(subsection_start)
end = int(subsection_start + len(inputs) / workers)
subsection_start = end
inputs_split.append( inputs[start:end] )
with Pool(workers) as p:
p.map(function_object, inputs_split)