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

149

Я сталкиваюсь с проблемами, пытаясь использовать большие объекты в 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
Вениамин
источник
Попробуйте использовать «free» для освобождения памяти другого неиспользуемого процесса.
Маноэль Гальдино
5
@ Маноэль Гальдино: Что такое «бесплатно»? Функция R?
Бенджамин
3
@Manoel: В R задача освобождения памяти выполняется сборщиком мусора, а не пользователем. Если вы работаете на уровне C, можно вручную Callocи с Freeпамятью, но я подозреваю, что это не то, что делает Бенджамин.
Шарпи
В библиотеке XML вы можете использовать бесплатно. Из документации: «Эта универсальная функция доступна для явного освобождения памяти, связанной с данным объектом. Она предназначена для использования на объектах внешнего указателя, которые не имеют функции / процедуры автоматического финализатора, которая очищает память, которая используется родной объект. "
Маноэль Гальдино

Ответы:

78

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

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

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

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

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

mdsumner
источник
1
задача - классификация изображений с помощью randomForest. Мне нужно иметь матрицу обучающих данных (до 60 полос) и от 20 000 до 6 000 000 строк для подачи в randomForest. В настоящее время я достигаю 150000 строк, потому что мне нужен непрерывный блок для хранения результирующего объекта randomForest ... Именно поэтому bigmemory не помогает, так как randomForest требует матричный объект.
Бенджамин
Что вы подразумеваете под «создавать только нужный вам объект за один сеанс»?
Бенджамин
создавайте 'a' только один раз, если вы ошиблись в первый раз, начните новый сеанс
mdsumner
1
Я хотел бы добавить, что для программ, которые содержат большие циклы, где выполняется много вычислений, но вывод относительно невелик, может быть более эффективным использование памяти для вызова внутренней части цикла через Rscript (из скрипта BASH или Python) и затем сопоставлять / объединять результаты в другом сценарии. Таким образом, память полностью освобождается после каждой итерации. Есть немного потраченных впустую вычислений от повторной загрузки / пересчета переменных, переданных в цикл, но по крайней мере вы можете обойти проблему с памятью.
Бенджамин
54

Для пользователей 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.
Тимоти Генри
источник
9
R делает сборку мусора самостоятельно, gc()это всего лишь иллюзия. Проверка Диспетчера задач - это просто очень простая операция с Windows. Единственный совет, с которым я могу согласиться, - это сохранение в формате .RData
Дэвид Аренбург,
3
@DavidArenburg gc () - иллюзия? Это означало бы, что картина, изображенная выше, показывающая падение использования памяти, является иллюзией. Я думаю, что вы не правы, но я могу ошибаться.
Тимоти Генри
4
Я не имел в виду, что gc()это не работает. Я просто имею в виду, что R делает это автоматически, поэтому вам не нужно делать это вручную. Смотрите здесь
Дэвид Аренбург
2
@DavidArenburg Я могу вам сказать, что падение использования памяти на рисунке выше вызвано командой gc (). Я не верю, что документ, на который вы указываете, является правильным, по крайней мере, не для моей установки (Windows, R версия 3.1.0 (2014-04-10) Платформа: i386-w64-mingw32 / i386 (32-разрядная версия)).
Тимоти Генри
15
Хорошо, в последний раз. gc() РАБОТАЕТ . Вам просто не нужно использовать это, потому что R делает это внутренне
Дэвид Аренбург
16

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

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

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

Саша Эпскамп
источник
4
Работает, кроме случаев, когда ожидается матричный класс (а не big.matrix)
Бенджамин
14

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

Дэвид Хеффернан
источник
25
В общем, это не лекарство - я переключился, и теперь у меня есть Error: cannot allocate vector of size ... Gb(но да, у меня много данных).
om-nom-nom
2
Может быть, не лекарство, но это очень помогает. Просто загрузите ОЗУ и продолжайте запускать memory.limit (). Или, возможно, подумайте о разделении / выборке ваших данных.
random_forest_fanatic
Если у вас возникают проблемы даже в 64-битной среде, которая по сути не ограничена, вероятно, вы пытаетесь выделить что-то действительно масштабное. Вы рассчитали, насколько большим должен быть вектор, теоретически? В противном случае может случиться так, что вашему компьютеру потребуется больше оперативной памяти, но вы можете иметь только так много.
hangmanwa7id
приятно попробовать простые решения, подобные этим, перед тем, как приступить к решению лицом к лицу. Спасибо.
Нова
Более того, это проблема не только с Windows. В настоящее время я работаю на Ubuntu, 64-битном R, использую Matrix и испытываю трудности с манипулированием объектом Matrix 20048 x 96448.
12

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

Кваку Дамоа
источник
11

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

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

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

Раджиб Кумар Де
источник
1
Почему за это проголосовали? Конечно, это опасный подход, но он часто помогает, если для сеанса нужно выделить немного больше памяти.
Джепп Олсен
3
Это только решение для Windows
Jinhua Wang
9

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

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

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

Nurit
источник
1
Могу ли я использовать это на экземпляре Amazon EC2? Если так, что я должен поставить вместо server_name? Я сталкиваюсь с этим, cannot allocate vector size...пытаясь создать огромную матрицу условий документа для AMI, и я не могу понять, почему у нее недостаточно памяти или сколько еще мне нужно арендовать. Спасибо!
seth127
Я новичок в Ubuntu и использую Rstudio на нем. У меня 16 ГБ оперативной памяти. Как мне применить процесс, который вы показываете в ответе. Спасибо
runjumpfly
3

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

# defrag memory 
save.image(file="temp.RData")
rm(list=ls())
load(file="temp.RData")
Саймон Вудворд
источник