我有一些多线程代码,其中每个线程调用一个函数f(df::DataFrame)
,该函数读取该DataFrame的列并查找该列大于0的索引:
function f(df::DataFrame)
X = df[:time]
return findall(x->x>0, X)
end
在主线程中,我读取了一个R * .rds文件,Julia将其转换为数据帧,并将其传递给f()
,如下所示:
rds = "blabla.rds"
objs = load(rds);
params = collect(0.5:0.005:0.7)
for i in 1:length(objs)
cols = [string(name) for name in names(objs.data[i]) if occursin("bla",string(name))]
hypers = [(a,b) for a in cols, b in params] # length ~2000
Threads.@threads for hi in 1:length(hypers) # MEMORY BLOWS UP HERE
df = f(objs.data[i])
end
end
传递到df
的每个f()
约为0.7GB。在运行多线程循环时分析内存使用情况,内存使用量将增加到约30GB。有25个线程,对f()
的调用约2000次。知道为什么内存爆炸了吗?
注意:如此频繁地在循环内调用GC.gc()似乎可以解决此问题,这似乎很不明智。 另请注意:无论我使用常规循环还是多线程循环,都会发生这种情况。
编辑: 按如下所示分析代码:
function foo(objs)
for i in 1:length(objs)
df = objs.data[i]
Threads.@threads for hi in 1:2000
tmp = f(df)
end
end
end
@benchmark(foo($objs))
给予
BenchmarkTools.Trial:
memory estimate: 32.93 GiB
allocs estimate: 48820
--------------
minimum time: 2.577 s (0.00% GC)
median time: 2.614 s (0.00% GC)
mean time: 2.614 s (0.00% GC)
maximum time: 2.651 s (0.00% GC)
--------------
samples: 2
evals/sample: 1