Утечка памяти при разборе больших XML-файлов с использованием Element Tree - PullRequest
0 голосов
/ 10 сентября 2018

Я использовал Element Tree в python для анализа моего xml-файла размером 66 GB для создания инвертированного индекса. Файл представляет собой XML-файл Википедии, который содержит около 17000000 документов в тегах <page>.

Из того, что я мог собрать в сети, связанной с анализом такого большого количества данных, я познакомился с использованием elem.clear(), который освобождает память, выделяемую каждому тегу после его использования. После прочтения каждого 8000 документов я записываю его в файл, стираю память, занятую для переменных, работающих с данными этих 8000 файлов, и затем снова запускаю.

До сих пор мне удавалось без проблем проанализировать 15GB файла, но теперь мой ноутбук замедлился до почти замороженного состояния. Может кто-нибудь сказать мне, где утечка памяти?

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

def parseXML(xmlfile):
    newsitems = []
    tempcnt=1
    pageSize=8000
    stop_words = set(stopwords.words('english'))
    nsmap={}
    totalWords=0
    invertedIndexNo=1
    news={}
    for event, elem in ET.iterparse(xmlfile, events=('start','end','start-ns','end-ns')):
        if event=='start-ns':
            ns,url=elem
            nsmap[ns]=url
        if event=='end':
            if elem.tag==fixtag('','id',nsmap) and elem.text is not None:
                    if news.get('i')==None:
                        news['i']=elem.text.encode('utf-8')
            elif elem.tag==fixtag('','title',nsmap) and elem.text is not None:
                news['t']=elem.text.encode('utf-8')
            elif elem.tag==fixtag('','text',nsmap) and elem.text is not None:
                news['b'], news['r'], news['g']=giveBodyRefCateg(elem.text)
            elif elem.tag==fixtag('','page',nsmap) and len(news)>0:
                newsitems.append(news)
                tempcnt+=1
                news={}
            elem.clear()
#         if getsizeof(newsitems)>0.1*1000*1000:
        if tempcnt>pageSize:
            invertedIndex=refine(newsitems,stop_words)
            writeBlockInvertedIndex(invertedIndex,invertedIndexNo)
            print(\"The size:\",getsizeof(newsitems),getsizeof(invertedIndex))
            invertedIndexNo+=1
            tempcnt=1
            totalWords+=len(invertedIndex)
            del newsitems[:]
            del invertedIndex
            gc.collect()

    invertedIndex=refine(newsitems,stop_words)
    writeBlockInvertedIndex(invertedIndex,invertedIndexNo)
    totalWords+=len(invertedIndex)

    del newsitems[:]
    return invertedIndexNo,totalWords
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...