Принудительное выполнение сборки мусора в R с помощью команды gc()

Периодически я программирую небрежно. Хорошо, я все время программирую небрежно, но иногда это настигает меня в виде ошибок нехватки памяти. Я начинаю проявлять небольшую дисциплину в удалении объектов с rm() команда и все становится лучше. Я вижу смешанные сообщения онлайн о том, должен ли я явно позвонить gc() после удаления больших объектов данных. Некоторые говорят, что прежде чем R вернет ошибку памяти, он запустится gc() в то время как другие говорят, что принуждение вручную gc хорошая идея

Должен ли я бежать gc() после удаления больших объектов, чтобы обеспечить максимальную доступность памяти?

6 ответов

Решение

"Наверное." Я делаю это тоже, и часто даже в цикле, как в

cleanMem <- function(n=10) { for (i in 1:n) gc() }

Однако, по моему опыту, это не восстанавливает память в первозданном состоянии.

Поэтому я обычно держу задачи под рукой в ​​файлах сценариев и выполняю их с помощью интерфейса r (в Unix и из пакета littler). Rscript - это альтернатива этой другой ОС.

Этот рабочий процесс согласуется с

который мы рассмотрели здесь раньше.

Со страницы помощи на gc:

Вызов gc вызывает сборку мусора. Это также будет происходить автоматически без вмешательства пользователя, и основная цель вызова "gc" - для отчета об использовании памяти.

Тем не менее, может быть полезно вызвать 'gc' после удаления большого объекта, так как это может побудить R вернуть память операционной системе.

Так что это может быть полезно, но в основном вам не нужно этого делать. Мое личное мнение, что это код последней инстанции - вы не должны засорять свой код gc() конечно, но если ваша машина продолжает падать, а вы пробовали все остальное, это может быть полезно.

Под всем остальным я имею в виду такие вещи, как

  1. Написание функций, а не сырые сценарии, поэтому переменные выходят за рамки.

  2. Очистка вашего рабочего пространства, если вы переходите от одной проблемы к другой, не связанной.

  3. Отбрасывая данные / переменные, которые вас не интересуют. (Я часто получаю электронные таблицы с десятками неинтересных столбцов.)

Немного опоздал на вечеринку, но:

Явный вызов gc освободит память "сейчас". ... так что если другим процессам нужна память, это может быть хорошей идеей. Например, перед звонком system или похожие. Или, возможно, когда вы "закончите" сценарий и R некоторое время будет бездействовать, пока не прибудет следующее задание - снова, чтобы другие процессы получили больше памяти.

Если вы просто хотите, чтобы ваш скрипт работал быстрее, это не имеет значения, поскольку R вызовет его позже, если потребуется. Это может быть даже медленнее, поскольку нормальному циклу GC, возможно, никогда не понадобилось бы его вызывать

... но если вы хотите, например, измерить время, обычно рекомендуется выполнить сборку мусора перед запуском теста. Это то, что system.time делает по умолчанию.

ОБНОВЛЕНИЕ Как указывает @DWin, R (или C#, или Java и т. Д.) Не всегда знают, когда памяти мало и GC должен работать. Таким образом, иногда вам может потребоваться выполнить сбор данных в качестве обходного пути для недостатков в системе памяти.

Предположительно, R использует только оперативную память. Это просто не соответствует действительности на Mac (и я подозреваю, что это не так и на Windows.) Если у него заканчивается ОЗУ, он начинает использовать виртуальную память. Иногда, но не всегда, процессы "распознают", что им нужно запустить gc() и освободить память. Когда они этого не делают, вы можете увидеть это, используя ActivityMonitor.app и увидев, что вся оперативная память занята и доступ к диску увеличился. Я обнаружил, что когда я выполняю большие регрессионные прогоны Кокса, я могу избежать перетекания в виртуальную память (при медленном доступе к диску), предшествуя вызовам с gc(); cph(...)

Нет. Если для операции недостаточно памяти, R запустится gc() автоматически.

"Может быть." У меня нет однозначного ответа. Но файл справки предполагает, что на самом деле есть только две причины для вызова gc():

  1. Вы хотите отчет об использовании памяти.
  2. После удаления большого объекта "он может предложить R вернуть память операционной системе".

Так как это может замедлить большую симуляцию с повторными вызовами, я обычно делал это только после удаления чего-то большого. Другими словами, я не думаю, что имеет смысл систематически называть это все время, если у вас нет веских причин для этого.

Другие вопросы по тегам