我一直在使用Julia进行大量数据的多线程处理,并观察到一种交互模式.内存使用情况(报告htop)缓慢增长,直到该进程被OS终止.该项目很复杂,很难生产出合适的MWE,但我进行了一个简单的实验:
using Base.Threads
f(n) = Threads.@threads for i=1:n
x = zeros(n)
end
Run Code Online (Sandbox Code Playgroud)
现在,我f(n)反复调用n的各种值(在我的64 Gb机器上大约10 ^ 4到10 ^ 5之间).结果是,有时一切都按预期工作,内存在返回后被释放,但有时情况并非如此,并且htop即使看起来没有进行计算,也会挂起大量值的已用内存量:
显式垃圾收集GC.gc()只能帮助一点,一些内存被释放,但只有一小块.此外,GC.gc()有时在函数循环中调用有f帮助,但问题仍然存在,当然,性能会降低.退出Julia后,分配的内存恢复正常(可能由操作系统释放).
我已经读过julia如何管理它的内存以及只有当内存计数大于某个值时才释放内存.但就我而言,它会导致进程被操作系统杀死.在我看来,GC不知何故失去了所有分配的内存
任何人都可以解释这种行为,以及如何通过重复调用来减少代码的速度来阻止它GC.gc()?为什么以这种方式破坏垃圾收集?
更多细节:
这是我的versioninfo输出:
julia> versioninfo()
Julia Version 0.7.0
Commit a4cb80f3ed (2018-08-08 06:46 UTC)
Platform Info:
OS: Linux (x86_64-pc-linux-gnu)
CPU: Intel(R) Xeon(R) Platinum 8124M CPU @ 3.00GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-6.0.0 (ORCJIT, skylake)
Environment:
JULIA_NUM_THREADS = 36
Run Code Online (Sandbox Code Playgroud)我想基于参数来评估导入模块的表达式expr.到目前为止,我想出了:
julia> expr = :(Base.Threads)
julia> @eval using $expr
ERROR: TypeError: import or using: expected Symbol, got Expr
Stacktrace:
[1] eval(::Module, ::Expr) at ./sysimg.jl:23
Run Code Online (Sandbox Code Playgroud)
一种可能性是Expr直接使用构造函数,如下所示:
julia> expr = [:Base, :Threads]
2-element Array{Symbol,1}:
:Base
:Threads
julia> eval(Expr(:using, expr...))
Run Code Online (Sandbox Code Playgroud)
但是有没有其他的,也许更直接的方式,而不需要构建Expr?