【发布时间】:2018-09-18 07:08:12
【问题描述】:
我一直在使用 Julia 对大量数据进行多线程处理,并观察到一种相互交织的模式。内存使用量(由htop 报告)缓慢增长,直到进程被操作系统杀死。项目复杂,很难做出合适的MWE,但我做了一个简单的实验:
using Base.Threads
f(n) = Threads.@threads for i=1:n
x = zeros(n)
end
现在,我为各种 n 值(在我的 64 Gb 机器上介于 10^4 和 10^5 之间)反复调用 f(n)。结果是有时一切都按预期工作,内存在返回后被释放,但有时情况并非如此,htop 报告的已用内存量保持在一个很大的值,即使似乎没有进行计算:
显式垃圾回收GC.gc() 帮助不大,释放了一些内存,但只有一小块。此外,有时在函数f 的循环中调用GC.gc() 会有所帮助,但问题仍然存在,当然,性能也会降低。退出 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
【问题讨论】:
-
我无法在 Julia v1.1 中重现此行为(未尝试 v0.7)。如果它仍然发生,那么这将是一个错误,您可能应该在 julialang slack 上询问或在 GitHub 上的 Julia 存储库上打开一个问题。