Удалить глобальную переменную и освободить память из функции - PullRequest
0 голосов
/ 29 мая 2019

Мне нужно удалить глобальную переменную и освободить память, которую она использовала, внутри функции с R, но ни одна из опций, которые я пробовал, не работает.

Я пробовал функцию rm с параметром envir, а затем gc, но gc не освобождает память. Я также попытался запустить gc в глобальной среде с помощью eval + envir.

library(data.table)
DT = data.table(col1 = 1:1e6)
cols = paste0('col', 2:100)
for (col in cols){ DT[, col := 1:1e6, with = F] }

rm_and_release <- function(dt){
  dt <- dt[sample(1e6, 9e5, FALSE)]
  print(gc())
  rm(DT, envir = globalenv())

  print(gc())
}

rm_and_release(DT)

Результат следующий

           used  (Mb) gc trigger   (Mb)  max used   (Mb)
Ncells   661556  35.4    1168576   62.5   1143443   61.1
Vcells 96303112  734.8   146725516 1119.5 146722586 1119.5
           used  (Mb) gc trigger   (Mb)  max used   (Mb)
Ncells   661569  35.4    1168576   62.5   1143443   61.1
Vcells 96303114  734.8   146725516 1119.5 146722586 1119.5

Я ожидал, что второй gc () освободит больше памяти, так как в этот момент есть только один набор данных, потому что глобальный DT был удален.

Мне нужно освободить ОЗУ внутри функции, потому что функция генерирует больше наборов данных, и ей не хватает памяти.

Ответы [ 2 ]

0 голосов
/ 30 мая 2019

Я нашел код, который работает

library(data.table)
DT = data.table(col1 = 1:1e6)
cols = paste0('col', 2:100)
for (col in cols){ DT[, col := 1:1e6, with = F] }

rm_and_release <- function(){
  dt <- copy(DT)
  dt <- dt[sample(1e6, 9e5, FALSE)]
  print(gc())
  rm(DT, envir = globalenv())

  print(gc())
}

rm_and_release()

В результате получается

           used  (Mb) gc trigger   (Mb)  max used   (Mb)
Ncells   865272  46.3    1442291   77.1   1280599   68.4
Vcells 96733883 738.1  167167064 1275.4 147681076 1126.8
           used  (Mb) gc trigger   (Mb)  max used   (Mb)
Ncells   865173  46.3    1442291   77.1   1280599   68.4
Vcells 46731629 356.6  133733651 1020.4 147681076 1126.8

Я думаю, очень уродливо не вставлять DT в качестве аргумента функции, но, по крайней мере, в этом случае память уменьшается с 738 МБ до 356 МБ, что крайне важно для того, что я делаю

0 голосов
/ 29 мая 2019

Используйте аргумент list= rm следующим образом:

library(data.table)
DT = data.table(col1 = 1:1e6)
cols = paste0('col', 2:100)
for (col in cols){ DT[, col := 1:1e6, with = F] }

rm_and_release <- function(dt){
  dt <- dt[sample(1e6, 9e5, FALSE)]
  print(gc())
  rm(list = "DT", envir = globalenv())

  print(gc())
}

rm_and_release(DT)
exists("DT")
## [1] FALSE

Примечание

Вот журнал, когда я его запускаю (в Windows):

> library(data.table)
> gc()
          used (Mb) gc trigger  (Mb) max used  (Mb)
Ncells 1075660 57.5    1899034 101.5  1899034 101.5
Vcells 2609137 20.0   91310117 696.7 99059673 755.8
> DT = data.table(col1 = 1:1e6)
> cols = paste0('col', 2:100)
> for (col in cols){ DT[, col := 1:1e6, with = F] }
There were 50 or more warnings (use warnings() to see the first 50)
> 
> rm_and_release <- function(dt){
+   dt <- dt[sample(1e6, 9e5, FALSE)]
+   print(gc())
+   rm(list = "DT", envir = globalenv())
+ 
+   print(gc())
+ }
> 
> gc()
           used  (Mb) gc trigger  (Mb) max used  (Mb)
Ncells  1076769  57.6    1899034 101.5  1899034 101.5
Vcells 53024698 404.6   91310117 696.7 99059673 755.8
> rm_and_release(DT)
           used  (Mb) gc trigger   (Mb) max used  (Mb)
Ncells  1075902  57.5    1899034  101.5  1899034 101.5
Vcells 97613454 744.8  134081733 1023.0 99059673 755.8
           used  (Mb) gc trigger   (Mb) max used  (Mb)
Ncells  1075901  57.5    1899034  101.5  1899034 101.5
Vcells 97613454 744.8  160978079 1228.2 99059673 755.8
> exists("DT")
[1] FALSE
> gc()
          used (Mb) gc trigger  (Mb) max used  (Mb)
Ncells 1075669 57.5    1899034 101.5  1899034 101.5
Vcells 2613271 20.0  128782463 982.6 99059673 755.8
> ## [1] FALSE
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...