Серьезная утечка памяти при итеративном разборе файлов XML

контекст

При переборе набора файлов Rdata (каждый из которых содержит вектор символов HTML-кода), которые загружаются, анализируются (с помощьюXML функциональность), а затем снова удалены из памяти, я испытываюсущественный увеличение потребления памяти процессом R (убивая процесс в конечном счете).

Это просто кажется

освобождение объектов черезfree(),удаляя их черезrm() а такжеБегgc()

не имеют никаких эффектов, поэтому потребление памяти накапливается до тех пор, пока не останется больше памяти.

РЕДАКТИРОВАТЬ 2012-02-13 23:30:00

Благодаря ценной информации, которой поделились автор и разработчик пакетаXMLДункан Темпл Лэнг (снова: я действительно очень ценю это!), Проблема, кажется, тесно связана с тем, как освобождаются внешние указатели и как сборка мусора обрабатывается в пакете XML. Дункан выпустил исправленную версию пакета (3.92-0), в которой объединены некоторые аспекты синтаксического анализа XML и HTML и улучшена сборка мусора, когда больше нет необходимости явно освобождать объект, содержащий внешний указатель, черезfree(), Вы найдете исходный код и бинарный файл Windows у ДунканаВеб-сайт омегахата.

РЕДАКТИРОВАТЬ 2012-02-13 23:34:00

К сожалению, новая версия пакета все еще не решает проблемы, с которыми я сталкиваюсь в небольшом небольшом примере, который я собрал. Я последовал некоторому предложению и немного упростил пример, чтобы было легче понять и найти соответствующие функции там, где кажется, что что-то идет не так (проверьте функции./lib/exampleRun.R а также.lib/scrape.R).

РЕДАКТИРОВАТЬ 2012-02-14 15:00:00

Дункан предложил попытаться принудительно освободить разобранный документ через.Call("RS_XML_forceFreeDoc", html), Я включил логический переключатель в примере (do.forcefree в сценарии./scripts/memory.R) что, если установленоTRUE, сделаю именно это. К сожалению, это привело к краху моей консоли R. Было бы здорово, если бы кто-то мог проверить это на своей машине! На самом деле, докдолжен быть освобожден автоматически при использовании последней версии XML (см. выше). Факт, что это не кажется ошибкой (согласно Дункану).

РЕДАКТИРОВАТЬ 2012-02-14 23:12:00

Дункан выдвинул еще одну версию XML (3.92-1) на свой веб-сайт OmegahatВеб-сайт омегахата, Это должно решить проблему в целом. Однако мне, кажется, не повезло с моим примером, поскольку я все еще испытываю ту же утечку памяти.

РЕДАКТИРОВАТЬ 17-02-2012, 20:39> РЕШЕНИЕ!

ДА! Дункан нашел и исправил ошибку! Это была небольшая опечатка в сценарии только для Windows, которая объясняла, почему ошибка не отображалась в Linux, Mac OS и т. Д. Проверьте последнюю версию3.92-2.! Потребление памяти стало таким же постоянным, как и при итеративном анализе и обработке файлов XML!

Отдельное спасибо Duncan Temple Lang и всем остальным, кто ответил на этот вопрос!

>>> ЧАСТИ УЧАСТИЯ ОРИГИНАЛЬНОГО ВОПРОСА <<<Пример инструкции (отредактировано 2012-02-14 15:00:00)Скачать папку'Память' от моегоGithub репо.Откройте скрипт./scripts/memory.R и установите а) вашрабочий каталог встрока 6б)пример объема встрока 16 а также c) принудительно ли освобождать проанализированный документ или нет встрока 22, Обратите внимание, что вы все еще можете найти старые скрипты; они помеченыLEGACY"в конце имени файла.Запустите скрипт.Исследуйте последний файл./memory_<TIMESTAMP>.txt чтобы увидеть увеличение зарегистрированных состояний памяти с течением времени. Я включил два текстовых файла, которые были получены в результате моих собственных тестов.Вещи, которые я сделал в отношении контроля памятиубедившись, что загруженный объект снова удаляется с помощьюrm() в конце каждой итерации.При разборе файлов XML я установил аргументaddFinalizer=TRUE, удалил все объекты R, которые имеют ссылку на проанализированный документ XML, прежде чем освобождать указатель C черезfree() и удаление объекта, содержащего внешний указатель.добавивgc() тут и там.пытаясь следовать советам в Дункан Темпл ЛэнгсПримечания на управление памятью при использовании его пакета XML (я должен признать, что я не полностью понял, что там сказано)

РЕДАКТИРОВАТЬ 13-02-2012 23:42:00: Как я уже говорил выше, явные призывы кfree() с последующимrm() не должно быть больше необходимости, поэтому я прокомментировал эти призывы.

Системная информацияWindows XP 32 бит, 4 ГБ оперативной памятиWindows 7 32 бит, 2 ГБ оперативной памятиWindows 7 64 бит, 4 ГБ оперативной памятиR 2.14.1XML 3.9-4XML 3.92-0, найденный наhttp://www.omegahat.org/RSXML/Начальные результаты на 2012-02-09 01:00:00Выполнение сценария webscraping на нескольких машинах (см. Раздел «Сведения о системе» выше) всегда снижает потребление памяти моим процессом R после примерно 180 - 350 итераций (в зависимости от ОС и ОЗУ).Запуск сценария простой rdata приводит к постоянному потреблению памятиесли и только если вы устанавливаете явный вызов сборщика мусора черезgc() в каждой итерации; иначе вы испытываете то же поведение, что и в сценарии веб-скрепинга.ВопросовЕсть идеи, что вызывает увеличение памяти?Есть идеи, как обойти это?Результаты по состоянию на 2012-02-013 23:44:00

Запуск примера в./scripts/memory.R на нескольких машинах (см. раздел «Сведения о системе» выше) все еще сбрасывает потребление памяти моим процессом R после примерно 180 - 350 итераций (в зависимости от ОС и ОЗУ).

Там все еще наблюдается очевидное увеличение потребления памяти, и, хотя, глядя на цифры, оно может показаться не таким уж большим, мои R-процессы всегда в какой-то момент умирают из-за этого.

Ниже я опубликовал несколько временных рядов, которые явились результатом запуска моего примера на 32-битной коробке WinXP с 2 ГБ ОЗУ:

TS_1 (XML 3.9-4, 2012-02-09)

29.07 33.32 30.55 35.32 30.76 30.94 31.13 31.33 35.44 32.34 33.21 32.18 35.46 35.73 35.76 35.68 35.84 35.6 33.49 33.58 33.71 33.82 33.91 34.04 34.15 34.23 37.85 34.68 34.88 35.05 35.2 35.4 35.52 35.66 35.81 35.91

TS_2 (XML 3.9-4, 2012-02-09)

28,54 30,13 32,95 30,33 30,43 30,54 35,81 30,99 32,78 31,37 31,56 35,22 31,99 32,22 32,55 32,66 32,84 35,32 33,59 33,32 33,47 33,58 33,69 33,76 33,87 35,5 35,52 34,24 37,67 34,75 34,92 35,1 37,97 35,43 35,57 35,7

Сообщение об ошибке, связанное с TS_2
[...]
Scraping html page 30 of ~/data/rdata/132.rdata
Scraping html page 31 of ~/data/rdata/132.rdata
error : Memory allocation failed : growing buffer
error : Memory allocation failed : growing buffer
I/O error : write error
Scraping html page 32 of ~/data/rdata/132.rdata
Fehler in htmlTreeParse(file = obj[x.html], useInternalNodes = TRUE, addFinalizer =     TRUE): 
 error in creating parser for (null)
> Synch18832464393836
TS_3 (XML 3.92-0, 2012-02-13)

24,14 24,47 20,1 22,03 25,21 25,54 23,15 23,5 26,71 24,6 27,39 24,93 28,06 25,64 28,74 26,36 29,3 27,07 30,01 27,77 28,13 31,13 28,84 31,79 29,54 32,4 30,25 33,07 30,96 33,76 31,66 34,4 32,37 35,1 33,07 35,77 38,23 34,16 34,51 34,87 35,22 35,58 35,93 40,54 40,9 41,33 41,6

Сообщение об ошибке, связанное с TS_3
[...]
---------- status: 31.33 % ----------

Scraping html page 1 of 50
Scraping html page 2 of 50
[...]
Scraping html page 36 of 50
Scraping html page 37 of 50
Fehler: 1: Memory allocation failed : growing buffer
2: Memory allocation failed : growing buffer
Изменить 2012-02-17: пожалуйста, помогите мне проверить значение счетчика

Вы бы оказали мне огромную услугу, если бы могли запустить следующий код.Это не займет больше 2 минут вашего времени, Все, что вам нужно сделать, это

СкачатьRdata файл и сохранить его какseed.Rdata.Загрузите скрипт, содержащий моискребковая функция и сохранить его какscrape.R.Исходный код приведен после соответствующей настройки рабочего каталога.

Код:

setwd("set/path/to/your/wd")
install.packages("XML", repos="http://www.omegahat.org/R")
library(XML)
source("scrape.R")
load("seed.rdata")
html <- htmlParse(obj[1], asText = TRUE)
counter.1 <- .Call("R_getXMLRefCount", html)
print(counter.1)
z <- scrape(html)
gc()
gc()
counter.2 <- .Call("R_getXMLRefCount", html)
print(counter.2)
rm(html)
gc()
gc()

Меня особенно интересуют ценностиcounter.1 а такжеcounter.2 которыйдолжен быть1 в обоих звонках. Фактически, именно на всех машинах Duncan проверил это. Однако, как выясняется,counter.2 имеет значение259 на всех моих машинах (см. подробности выше), и это именно то, что вызывает мою проблему.

Ответы на вопрос(2)

Ваш ответ на вопрос