Почему загрузка кэшированных объектов резко увеличивает потребление памяти, тогда как их вычисление не будет? - PullRequest
8 голосов
/ 31 октября 2011

Соответствующая справочная информация

Я создал небольшое программное обеспечение, которое можно настроить с помощью файла конфигурации. Файл конфигурации анализируется и переводится во вложенную структуру среды (например, .HIVE $ db = среда, .HIVE $ db $ user = "Horst", .HIVE $ db $ pw = "мой пароль", .HIVE $ regex $ дата = некоторое регулярное выражение для дат и т. д.)

Я создал подпрограммы, которые могут обрабатывать эти вложенные среды (например, искать значение «db / user» или «regex / date», изменять его и т. Д.). Дело в том, что первоначальный анализ файлов конфигурации занимает много времени и приводит к довольно большим объектам (на самом деле три к четырем, от 4 до 16 МБ). Поэтому я подумал: «Нет проблем, давайте просто кешируем их, сохраняя объекты в файлах .Rdata». Это работает, но «загрузка» кэшированных объектов заставляет мой процесс Rterm идти вверх, что связано с потреблением ОЗУ (более 1 ГБ !!), и я до сих пор не понимаю, почему (это не происходит когда я «вычисляю» объект заново, но это именно то, чего я пытаюсь избежать, так как это занимает слишком много времени).

Я уже думал о том, чтобы, возможно, сериализовать его, но я не тестировал его, так как мне нужно было бы немного изменить свой код. Кроме того, я не уверен, повлияет ли это на часть «загрузка обратно в R» так же, как загрузка файлов .Rdata.

Вопрос

Может кто-нибудь сказать мне, почему загрузка ранее вычисленного объекта оказывает такое влияние на потребление памяти моим процессом Rterm (по сравнению с вычислением его в каждом новом процессе, который я запускаю) и как лучше всего избежать этого?

При желании я также попытаюсь привести пример, но немного сложно воспроизвести мой точный сценарий. Еще попробую.

Ответы [ 2 ]

8 голосов
/ 31 октября 2011

Вероятно, потому что окружающая среда, которую вы создаете, распространяется вокруг их предков.Если вам не нужна информация о предке, установите для родителей таких сред значение emptyenv() (или просто не используйте среды, если они вам не нужны).

Также обратите внимание, что формулы (и,конечно, функции) имеют среду, так что следите за ней тоже.

3 голосов
/ 31 октября 2011

Если это не воспроизводится другими, будет трудно ответить. Однако я делаю нечто очень похожее на то, что вы делаете, но я использую файлы JSON для хранения всех своих значений. Вместо того, чтобы анализировать текст, я использую RJSONIO, чтобы преобразовать все в список, и получить материал из списка очень легко. (Вы можете, если хотите, конвертировать в хеш, но хорошо иметь слои вложенных параметров.)

См. этот ответ для примера того, как я делал такие вещи. Если это сработает для вас, вы можете отказаться от дорогостоящего шага перевода и всплывающего воспоминания.

(Делая удар по первоначальному вопросу ...) Интересно, ваша проблема в том, что вы используете среду, а не список. Сохранение среды может быть сложным в некоторых контекстах. Сохранение списков не проблема. Попробуйте использовать список или конвертировать в / из среды. Для этого вы можете использовать функции as.list() и as.environment().

...