Как память управляется при перезаписи объектов R?
Я обрабатываю некоторые большие наборы данных и делаю все возможное, чтобы оставаться под ограничениями памяти R. Возник вопрос о перезаписи объектов R. У меня большой data.table
(или любой объект R), и его нужно скопировать в tmp
несколько раз. Вопрос в следующем: не имеет значения, удалю ли я tmp
, прежде чем перезаписывать его? В коде:
for (1:lots_of_times) {
v_l_d_t_tmp <- copy(very_large_data_table) # Necessary copy of 7GB data
# table on 16GB machine. I can
# afford 2 but not 3 copies.
### do stuff to v_l_d_t_tmp and output
rm (v_l_d_t_tmp) # The question is whether this rm keeps max memory
# usage lower, or if it is equivalent to what an
# overwrite will automatically do on the next iteration.
}
Предположим, что необходима копия (если я дойду до точки, где мне нужно читать very_large_data_table
с диска в каждом цикле, я сделаю это, но вопрос стоит: будет ли разница в максимальном использовании памяти, если я явным образом удаляю v_l_d_t_tmp
перед загрузкой в нее снова?).
Или, чтобы научить человека ловить рыбу, что я мог набрать (в пределах R, не вмешиваться в ps
), чтобы ответить на это сам?
Это вполне нормально, если ответ получится: "Доверять сборку мусора".
Ответы
Ответ 1
Здесь другая идея... она напрямую не отвечает на ваш вопрос, вместо этого пытается обойти ее, устранив проблему памяти по-другому. Можете подумать:
Что делать, если вы вместо этого кешируете файл very_large_data_table, а затем читаете его только один раз, делаете то, что вам нужно сделать, а затем выходите из R. Теперь напишите цикл вне R, и проблема с памятью исчезнет. Конечно, это стоит вам больше, потому что вам нужно читать в 7 ГБ несколько раз... но это может стоить экономии расходов на память. Фактически, это уменьшает использование вашей памяти, поскольку вам не нужно когда-либо копировать таблицу.
Кроме того, как @konvas указал в комментариях, я также обнаружил, что rm()
даже с gc()
никогда не получал мне то, что мне нужно, с длинным циклом, память просто накапливалась бы и, в конечном итоге, падала. Выход из R - легкий выход.
Мне приходилось делать это так часто, что я написал пакет, чтобы помочь мне кэшировать такие объекты: simpleCache
Если вы заинтересованы в попытке, это будет выглядеть примерно так:
сделать это вне R:
for (1:lots_of_times) {
Rscript my_script.R
}
Затем в R сделайте это... my_script.R:
library(simpleCache)
simpleCache("very_large_data_table", {r code for how
you make this table }, assignTo="v_l_d_t_tmp")
### do stuff to v_l_d_t_tmp and output
Ответ 2
Это комментарий больше, чем ответ, но он становится слишком длинным.
Я предполагаю, что в этом случае вызов rm
может быть правильным. Я думаю, что, начиная со второй итерации, у вас может быть 3 таблицы в памяти, если вы не вызываете rm
. При копировании большого объекта R не может освободить память, занятую v_l_d_t_tmp
до конца копии, поскольку вызов функции может иметь ошибку, и в этом случае старый объект должен быть сохранен. Рассмотрим этот пример:
x<-1:10
myfunc<-function(y) {Sys.sleep(3);30}
Здесь я определил объект и функцию, которая занимает некоторое время, чтобы что-то сделать. Если вы попытаетесь:
x<-myfunc()
и разорвать выполнение до того, как оно закончится "естественно", объект x
все еще существует с его содержимым 1:10
. Итак, я предполагаю, что в вашем случае, даже если вы используете один и тот же символ, R не может освободить его содержимое до или во время копирования. Он может, если вы удалите его перед следующей копией. Конечно, объект будет удален после копии, но в нем может быть нехватка памяти.
Я никоим образом не являюсь экспертом из внутренних органов R, поэтому не считаю само собой разумеющимся то, что я только что сказал.