R управление памятью / невозможно выделить вектор размером n МБ

У меня возникают проблемы при попытке использовать большие объекты в R. Например:

> memory.limit(4000)
> a = matrix(NA, 1500000, 60)
> a = matrix(NA, 2500000, 60)
> a = matrix(NA, 3500000, 60)
Error: cannot allocate vector of size 801.1 Mb
> a = matrix(NA, 2500000, 60)
Error: cannot allocate vector of size 572.2 Mb # Can't go smaller anymore
> rm(list=ls(all=TRUE))
> a = matrix(NA, 3500000, 60) # Now it works
> b = matrix(NA, 3500000, 60)
Error: cannot allocate vector of size 801.1 Mb # But that is all there is room for

Я понимаю, что это связано с трудностью получения непрерывных блоков памяти (из здесь):

Начало сообщений об ошибках не может выделить вектор размера, что указывает на сбой в получении памяти, либо потому, что размер превысил ограничение адресного пространства для процесса, либо, что более вероятно, потому, что система не смогла предоставить память. Обратите внимание, что в 32-битной сборке вполне может быть достаточно свободной памяти, но недостаточно большого непрерывного блока адресного пространства, в который можно было бы его отобразить.

Как я могу это обойти? Моя основная трудность заключается в том, что я дохожу до определенного момента в моем скрипте, и R не может выделить 200-300 МБ для объекта ... Я не могу заранее выделить блок, потому что мне нужна память для другой обработки. Это происходит даже тогда, когда я старательно удаляю ненужные предметы.

РЕДАКТИРОВАТЬ: Да, извините: Windows XP SP3, 4 Гб ОЗУ, R 2.12.0:

> sessionInfo()
R version 2.12.0 (2010-10-15)
Platform: i386-pc-mingw32/i386 (32-bit)

locale:
[1] LC_COLLATE=English_Caribbean.1252  LC_CTYPE=English_Caribbean.1252   
[3] LC_MONETARY=English_Caribbean.1252 LC_NUMERIC=C                      
[5] LC_TIME=English_Caribbean.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

person Benjamin    schedule 02.03.2011    source источник
comment
Попробуйте использовать «бесплатно», чтобы освободить память другого неиспользуемого процесса.   -  person Manoel Galdino    schedule 02.03.2011
comment
@ Маноэль Галдино: Что такое «бесплатно»? Функция R?   -  person Benjamin    schedule 02.03.2011
comment
@Manoel: В R задача освобождения памяти выполняется сборщиком мусора, а не пользователем. При работе на уровне C можно вручную Calloc и Free память, но я подозреваю, что Бенджамин не этим занимается.   -  person Sharpie    schedule 03.03.2011
comment
В библиотеке XML можно использовать бесплатно. Из документации: Эта универсальная функция доступна для явного освобождения памяти, связанной с данным объектом. Он предназначен для использования с объектами внешнего указателя, не имеющими функции / подпрограммы автоматического финализатора, очищающей память, используемую собственным объектом.   -  person Manoel Galdino    schedule 03.03.2011


Ответы (9)


Подумайте, действительно ли вам нужны все эти данные явно или матрица может быть разреженной? В R имеется хорошая поддержка (например, см. Пакет Matrix) для разреженных матриц.

Сведите к минимуму все другие процессы и объекты в R, когда вам нужно создавать объекты такого размера. Используйте gc(), чтобы очистить неиспользуемую память, или, что лучше, создайте только тот объект, который вам нужен, за один сеанс.

Если вышеперечисленное не может помочь, возьмите 64-разрядную машину с таким объемом оперативной памяти, который вы можете себе позволить, и установите 64-разрядный R.

Если вы не можете этого сделать, существует множество онлайн-сервисов для удаленных вычислений.

Если вы не можете этого сделать, инструменты отображения памяти, такие как пакет ff (или bigmemory, как упоминает Саша), помогут вам создать новое решение. По моему ограниченному опыту, ff - это более продвинутый пакет, но вам следует прочитать тему High Performance Computing о обзорах задач CRAN.

person mdsumner    schedule 02.03.2011
comment
задача - классификация изображений, с randomForest. Мне нужна матрица обучающих данных (до 60 полос) и от 20 000 до 6 000 000 строк для передачи в randomForest. В настоящее время я максимально использую около 150 000 строк, потому что мне нужен непрерывный блок для хранения результирующего объекта randomForest ... Вот почему bigmemory не помогает, поскольку randomForest требует матричного объекта. - person Benjamin; 03.03.2011
comment
Что вы имеете в виду, говоря о создании только того объекта, который вам нужен, за один сеанс? - person Benjamin; 03.03.2011
comment
создайте только один раз, если вы ошиблись при первом запуске нового сеанса - person mdsumner; 07.03.2011
comment
Я бы добавил, что для программ, которые содержат большие циклы, где выполняется много вычислений, но вывод относительно невелик, может быть более эффективным с точки зрения памяти вызвать внутреннюю часть цикла через Rscript (из BASH или Python Script) , а затем сопоставить / объединить результаты в другом скрипте. Таким образом, память полностью освобождается после каждой итерации. Существует немного лишних вычислений из-за повторной загрузки / повторного вычисления переменных, переданных в цикл, но, по крайней мере, вы можете обойти проблему с памятью. - person Benjamin; 04.03.2016

Для пользователей Windows следующее очень помогло мне понять некоторые ограничения памяти:

  • перед открытием R откройте Монитор ресурсов Windows (Ctrl-Alt-Delete / Запустить диспетчер задач / вкладка «Производительность» / нажмите нижнюю кнопку «Монитор ресурсов» / вкладка «Память»)
  • вы увидите, сколько оперативной памяти мы уже использовали до того, как вы открыли R, и какими приложениями. В моем случае используется 1,6 ГБ из 4 ГБ. Так что я смогу получить только 2,4 ГБ для R, но теперь становится еще хуже ...
  • откройте R и создайте набор данных размером 1,5 ГБ, затем уменьшите его размер до 0,5 ГБ. Монитор ресурсов показывает, что моя оперативная память используется почти на 95%.
  • используйте gc() для сборки мусора => он работает, я вижу, что использование памяти уменьшилось до 2 ГБ

введите описание изображения здесь

Дополнительный совет, который работает на моей машине:

  • подготовить функции, сохранить как файл RData, закрыть R, повторно открыть R и загрузить функции поезда. Диспетчер ресурсов обычно показывает меньшее использование памяти, что означает, что даже gc () не восстанавливает всю возможную память, и закрытие / повторное открытие R работает лучше всего, чтобы начать с максимальным объемом доступной памяти.
  • Другой трюк состоит в том, чтобы загружать только набор поездов для обучения (не загружайте набор тестов, который обычно может составлять половину размера набора поездов). Фаза обучения может использовать память по максимуму (100%), поэтому все, что доступно, полезно. Все это следует воспринимать с недоверием, поскольку я экспериментирую с ограничениями памяти R.
person Timothée HENRY    schedule 15.07.2014
comment
R выполняет сборку мусора самостоятельно, gc() это просто иллюзия. Проверка диспетчера задач - это очень простая операция Windows. Единственный совет, с которым я могу согласиться, это сохранение в формате .RData. - person David Arenburg; 15.07.2014
comment
@DavidArenburg gc () - это иллюзия? Это означало бы, что изображение, показанное мною выше, демонстрирующее снижение использования памяти, является иллюзией. Я думаю, что вы ошибаетесь, но могу ошибаться. - person Timothée HENRY; 15.07.2014
comment
Я не имел в виду, что gc() не работает. Я просто имею в виду, что R делает это автоматически, поэтому вам не нужно делать это вручную. См. здесь - person David Arenburg; 15.07.2014
comment
@DavidArenburg Я могу точно сказать, что падение использования памяти на картинке выше связано с командой gc (). Я не верю, что документ, на который вы указываете, верен, по крайней мере, для моей установки (Windows, R версия 3.1.0 (2014-04-10) Платформа: i386-w64-mingw32 / i386 (32-разрядная версия)). - person Timothée HENRY; 15.07.2014
comment
Хорошо, в последний раз. gc() ДЕЙСТВИТЕЛЬНО работает. Вам просто не нужно его использовать, потому что R делает это внутри - person David Arenburg; 15.07.2014
comment
Есть только один случай, когда gc() может использоваться: свободная память для другого процесса, кроме R. Освобождение ОЗУ для запроса ее сразу после этого - это просто трата времени с free и malloc вызовами под капотом. - person Tensibai; 28.09.2016
comment
Я хотел бы добавить, что gc () работал только после того, как я использовал rm (). У меня был список векторов, которые я удалил через rm (list = ls (pattern = something)). После этого звонка мой баран по-прежнему не отличался. Затем я набрал gc (), и мой баран очистил 4 ГБ. Для этого есть причина? Я обнаружил, что R не делает это автоматически, как предлагает @DavidArenburg (по крайней мере, из-за моего нетерпения). Я начал добавлять gc () в конец своих скриптов, когда имею дело с очень большими фреймами данных. - person MadmanLee; 26.04.2017
comment
@MadmanLee, конечно, нет, зачем ему просить процессор освободить оперативную память, если никто не спрашивает? Он освободит его, если он ему понадобится (при следующей записи, если необходимо). Это похоже на то, как если бы вы периодически опорожняли и закрывали ящики на полке, в следующий раз, когда вам нужно что-то хранить, вам придется снова открыть ящик и положить его. Это больше операции, чем нужно. gc () запускается, когда вам нужно написать что-то, что не умещается в реальной свободной памяти, он сканирует ящики, чтобы очистить те, которые больше не нужны, чтобы сохранить то, что ему нужно записать. Вы испортили то, что R запросил у ОС и какое место свободно в выделенной памяти R. - person Tensibai; 09.01.2018
comment
@MadmanLee просто rm-объекты, которые вам больше не нужны, и пусть R сделает все остальное самостоятельно, это будет более эффективно. - person Tensibai; 09.01.2018
comment
@tensibai. У меня были проблемы с этим раньше. R не выгружает память перед загрузкой другого большого объекта. Мой компьютер зависает, а затем вылетает, если я не сделаю вышеуказанное решение. - person MadmanLee; 10.01.2018

Я перешел на страницу справки memory.limit и обнаружил, что на моем компьютере R по умолчанию может использовать до ~ 1,5 ГБ ОЗУ и что пользователь может увеличить этот предел. Используя следующий код,

>memory.limit()
[1] 1535.875
> memory.limit(size=1800)

помог мне решить мою проблему.

person Rajib Kumar De    schedule 21.09.2018
comment
Почему это отклоняется? Конечно, это опасный подход, но он часто может помочь, если для работы сеанса нужно выделить немного больше памяти. - person Jeppe Olsen; 10.01.2019
comment
Это только решение для Windows - person Jinhua Wang; 16.01.2020
comment
ржу не могу. Мне нужен был memory.limit(size=7000). Я использую windows 10 и R x64, кстати. - person Nip; 28.09.2020
comment
@JeppeOlsen Почему это опасный подход? - person melbez; 07.10.2020

Вот презентация по этой теме, которая может вас заинтересовать:

http://www.bytemining.com/2010/08/taking-r-to-the-limit-part-ii-large-datasets-in-r/

Я сам не пробовал обсуждать, но пакет bigmemory кажется очень полезным

person Sacha Epskamp    schedule 02.03.2011
comment
Работает, кроме случаев, когда ожидается матричный класс (а не big.matrix) - person Benjamin; 02.03.2011

Самый простой способ обойти это ограничение - перейти на 64-битный R.

person David Heffernan    schedule 03.03.2011
comment
В общем, это не лекарство - я переключился, и теперь у меня вместо него Error: cannot allocate vector of size ... Gb (но да, у меня много данных). - person om-nom-nom; 11.04.2012
comment
Может, и не лекарство, но очень помогает. Просто загрузите RAM и продолжайте увеличивать memory.limit (). Или, может быть, подумайте о разделении / выборке ваших данных. - person random_forest_fanatic; 29.07.2013
comment
Если у вас проблемы даже с 64-битной версией, которая по сути неограничена, возможно, вы пытаетесь выделить что-то действительно массивное. Вы вычислили, насколько большим должен быть вектор теоретически? В противном случае вашему компьютеру может потребоваться больше оперативной памяти, но вы можете иметь только ее. - person hangmanwa7id; 21.02.2015
comment
Хорошо бы попробовать такие простые решения, прежде чем делать больше решений, стоящих лицом к лицу. Спасибо. - person Nova; 07.03.2017
comment
Более того, это проблема не только Windows. В настоящее время я использую Ubuntu, 64-разрядную версию R, использую Matrix, и мне трудно управлять объектом Matrix 20048 x 96448. - person ; 22.05.2018
comment
@JanGalkowski Плотная матрица? Не можете найти более эффективную структуру данных? - person David Heffernan; 22.05.2018
comment
@DavidHefferman, Конечно, могу. Но дело в том, что эта проблема касается не только Windows. По крайней мере, в Windows я могу сказать memory.limit (size = 80000) и, если моя система поддерживает, и если она работает с R64, она будет выделяться. Да, конечно, я исправил проблему, уменьшив количество столбцов с помощью специальных средств. Эта матрица начала свою жизнь как матрица, то есть разреженная. Но если я хочу сделать что-то вроде центра его записей, это преимущество быстро рассеивается. - person ; 23.05.2018
comment
@Jan Ну, а кто что сказал про Windows? Это ты сказал это. - person David Heffernan; 23.05.2018
comment
@DavidHefferman Конечно. Но этот разговор / обмен / что угодно не происходит изолированно. Но, в любом случае, ничего. Я просто буду использовать Windows там, где мне нужно. - person ; 24.05.2018

Я столкнулся с подобной проблемой, и я использовал 2 флешки в качестве ReadyBoost. Два диска дали дополнительный прирост памяти на 8 ГБ (для кеша), и это решило проблему, а также увеличило скорость системы в целом. Чтобы использовать Readyboost, щелкните диск правой кнопкой мыши, перейдите в «Свойства», выберите «ReadyBoost», выберите переключатель «Использовать это устройство» и нажмите «Применить» или «ОК» для настройки.

person Kwaku Damoah    schedule 10.12.2015

Если вы запускаете свой скрипт в среде Linux, вы можете использовать эту команду:

bsub -q server_name -R "rusage[mem=requested_memory]" "Rscript script_name.R"

и сервер выделит вам запрошенную память (в соответствии с ограничениями сервера, но с хорошим сервером - можно использовать огромные файлы)

person nurit    schedule 10.09.2015
comment
Могу ли я использовать это на инстансе Amazon EC2? Если да, то что мне заменить server_name? Я сталкиваюсь с этим cannot allocate vector size..., пытаясь создать огромную матрицу условий документа на AMI, и я не могу понять, почему у него недостаточно памяти или сколько еще мне нужно арендовать. Спасибо! - person seth127; 15.03.2016
comment
Я новичок в Ubuntu и использую на нем Rstudio. У меня 16 ГБ ОЗУ. Как мне применить процесс, который вы показываете в ответе. Спасибо - person runjumpfly; 21.10.2016

Один из вариантов - до и после выполнения вашей команды, которая приводит к высокому потреблению памяти для выполнения сборки мусора путем выполнения команды gc(), это освободит память для вашего анализа в дополнение к использованию команды memory.limit().

Пример:

gc()
memory.limit(9999999999)
fit <-lm(Y ~ X)
gc() 
person Jalles10    schedule 14.03.2021
comment
Большое спасибо! Используя этот метод, я смог рассчитать матрицу расстояний для 21k + позиций. Размер результирующей матрицы расстояний составляет 3,5 ГБ. Windows 10, 16 ГБ, R 4.0.3, RStudio 1.3.1093 [скоро должно обновиться] - person mjaniec; 15.05.2021

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

# defrag memory 
save.image(file="temp.RData")
rm(list=ls())
load(file="temp.RData")
person Simon Woodward    schedule 26.02.2018