Память не освобождается в нескольких потоках - PullRequest
0 голосов
/ 18 сентября 2018

Я использую Julia для многопоточной обработки больших объемов данных и наблюдаю один пересекающийся шаблон. Использование памяти (сообщается htop) медленно растет, пока процесс не будет остановлен ОС. Проект сложный, и сложно создать подходящий MWE, но я провел простой эксперимент:

using Base.Threads
f(n) = Threads.@threads for i=1:n
    x = zeros(n)
end

Теперь я неоднократно вызывал f(n) для различных значений n (где-то между 10 ^ 4 и 10 ^ 5 на моей машине на 64 Гб). В результате иногда все работает, как ожидалось, и память возвращается после возврата, однако иногда это не так, и объем используемой памяти, сообщаемый htop, зависает при большом значении, даже если кажется, что вычисления не производятся:

enter image description here

Явный сбор мусора GC.gc() помогает только немного, освобождается некоторая память, но только небольшой кусок. Также помогает вызов GC.gc() иногда в цикле в функции f, но проблема сохраняется, и, конечно, производительность снижается. После выхода из 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
    
...