Как память управляется при перезаписи объектов 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, поэтому не считаю само собой разумеющимся то, что я только что сказал.