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


149

Я стикаюся з проблемами, які намагаються використовувати великі об'єкти в Р. Наприклад:

> 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 Мб для об'єкта ... Я не можу реально попередньо виділити блок, тому що мені потрібна пам'ять для іншої обробки. Це трапляється навіть тоді, коли я старанно видаляю зайві предмети.

EDIT: Так, вибачте: 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

Спробуйте використовувати "безкоштовно", щоб виділити пам'ять інших процесів, які не використовуються.
Маноел Галдіно

5
@ Manoel Galdino: Що таке "безкоштовно"? R функція?
Бенджамін

3
@Manoel: У R завдання із звільнення пам'яті вирішується сміттєзбірником, а не користувачем. Якщо ви працюєте на рівні С, можна вручну Callocта Freeпам'ять, але я підозрюю, що це не те, що робить Бенджамін.
Шарпі

У бібліотеці XML ви можете користуватися безкоштовно. З документації: "Ця загальна функція доступна для явного звільнення пам'яті, пов'язаної з даним об'єктом. Вона призначена для використання на зовнішніх об'єктах вказівника, які не мають функції / процедури автоматичного завершення, що очищає пам'ять, яку використовує рідний об’єкт ".
Маноел Галдіно

Відповіді:


78

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

Зведіть до мінімуму всі інші процеси та об’єкти в R, коли вам потрібно зробити об'єкти такого розміру. Використовуйте gc()для очищення невикористаної пам'яті, а краще створити потрібний вам об'єкт за один сеанс .

Якщо вищезгадане не допоможе, оберіть 64-розрядну машину з стільки оперативної пам’яті, скільки ви можете собі дозволити, і встановіть 64-бітний Р.

Якщо ви не можете цього зробити, існує багато онлайн-сервісів для віддалених обчислень.

Якщо ви не можете зробити це, інструменти для відображення пам'яті, такі як пакет ff(або bigmemoryяк згадує Саша), допоможуть вам створити нове рішення. За моїм обмеженим досвідом, ffце більш просунутий пакет, але ви повинні прочитати High Performance Computingтему CRAN Task Views.


1
завдання - класифікація зображень, з випадковимForest. Мені потрібно мати матрицю даних про тренування (до 60 смуг) і десь від 20 000 до 6 000 000 рядків, щоб подати до randomForest. В даний час я максимум на приблизно 150 000 рядків, тому що мені потрібен суміжний блок, щоб утримувати результуючий об'єкт randomForest ... Тому також bigmemory не допомагає, оскільки randomForest вимагає матричний об'єкт.
Бенджамін

Що ви маєте на увазі під "створенням лише потрібного вам об'єкта за один сеанс"?
Бенджамін

створіть "a" лише один раз, якщо ви помилитесь, перший раз запустити новий сеанс
mdsumner

1
Я додам, що для програм, що містять великі цикли, де проводиться велика кількість обчислень, але вихід порівняно невеликий, можна викликати більшу пам'ять, щоб викликати внутрішню частину циклу через Rscript (з BASH або Python Script) , а потім зіставити / зібрати результати в іншому сценарії. Таким чином, пам'ять повністю звільняється після кожної ітерації. Існує трохи витрачених витрат на повторне завантаження / повторне обчислення змінних, переданих у цикл, але принаймні ви можете обійти проблему з пам'яттю.
Бенджамін

54

Для користувачів Windows, мені дуже допомогло зрозуміти деякі обмеження пам’яті:

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

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

Додаткова порада, яка працює на моїй машині:

  • підготуйте функції, збережіть як файл RData, закрийте R, повторно відкрийте R та завантажте функції поїзда. Менеджер ресурсів, як правило, демонструє менший обсяг пам’яті, що означає, що навіть gc () не відновлює всю можливу пам'ять, а закриття / повторне відкриття R працює найкраще, щоб почати з максимальної кількості пам'яті .
  • інший трюк - це завантажувати лише поїзний набір для тренувань (не завантажувати тестовий набір, який, як правило, може бути наполовину меншим, ніж комплект поїздів). Навчальний етап може використовувати максимум пам'яті (100%), тому все, що є в нагоді, є корисним. Все це потрібно взяти з зерном солі, коли я експериментую з межами R пам'яті.

9
Збирання сміття самостійно, gc()є лише ілюзією. Перевірка диспетчера завдань - просто дуже основна операція Windows. Єдина порада, з якою я можу погодитися - це збереження у форматі .RData
Девід Аренбург

3
@DavidArenburg gc () - ілюзія? Це означатиме, що картина, яку я маю вище, показує падіння використання пам'яті, є ілюзією. Я думаю, ви помиляєтесь, але я можу помилитися.
Timothée HENRY

4
Я не мав на увазі, що gc()це не працює. Я просто маю на увазі, що R робить це автоматично, тому вам не потрібно робити це вручну. Дивіться тут
Девід Аренбург

2
@DavidArenburg Я можу вам сказати за факт, що падіння використання пам'яті на малюнку вище пояснюється командою gc (). Я не вірю, що документ, на який ви вказуєте, є правильним, принаймні, не для моєї установки (Windows, R версія 3.1.0 (2014-04-10) Платформа: i386-w64-mingw32 / i386 (32-розрядна)).
Timothée HENRY

15
Гаразд, востаннє. gc() НЕ працює. Вам просто не потрібно використовувати його, тому що R робить це інтернаціонально
Девід Аренбург

16

Ось презентація на цю тему, яка вам може бути цікавою:

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

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


4
Працює, за винятком випадків, коли очікується матричний клас (а не великий.матриця)
Бенджамін

14

Найпростіший спосіб обійти це обмеження - перейти на 64-бітний R.


25
Це взагалі не є ліком - я перейшов, і тепер Error: cannot allocate vector of size ... Gbзамість цього (але так, у мене дуже багато даних).
om-nom-nom

2
Можливо, це не є лікуванням, але це допомагає багато. Просто завантажте оперативну пам’ять і продовжуйте натягувати пам'ять.limit (). Або, можливо, подумайте про розподіл / вибірку даних.
random_forest_fanatic

Якщо у вас виникають проблеми навіть у 64-розрядному, який по суті є необмеженим, ви, мабуть, більше намагаєтесь виділити щось дійсно масове. Ви обчислили, наскільки теоретично повинен бути великий вектор? Інакше може статися, що вашому комп'ютеру потрібно більше оперативної пам’яті, але ви можете мати лише стільки, скільки можете.
hangmanwa7id

приємно спробувати такі прості рішення, як раніше, ніж більше рішень проти стін. Дякую.
Нова

Більше того, це не виключно проблема з Windows. В даний час я працюю на Ubuntu, 64-розрядному R, використовуючи 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"

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


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")
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.