2017-03-05 149 views
1

我遇到內存泄漏的一個醜陋的情況。我用beutifulsoup創建一個對象,然後通過自己的方法處理它。我正在用〜2000個XML文件來做這件事。處理大約一半後,程序停止由於工作的MemoryError,而且性能不斷退化。我試圖經由上__del__一個soup.decompose方法來解決這個問題,並迫使GC.Collect的處理每個文件之後。Beautifulsoup內存泄露

class FloorSoup: 
def __init__(self, f_id): 
    only_needed = SoupStrainer(["beacons", 'hint']) 
    try: 
     self.f_soup = BeautifulSoup(open("Data/xmls/floors/floors_" + f_id + ".xml", encoding='utf8'), "lxml", parse_only = only_needed) 
    except (FileNotFoundError): 
     print("File: Data/xmls/floors/floors_" + f_id + ".xml not found") 

def __del__(self): 
    self.f_soup.decompose() 

def find_floor_npcs(self): 
    found_npcs = set() 
    for npc in self.f_soup.find_all(text="npc"): 
     found_npcs.add(npc.parent.parent.values.string) 
    return found_npcs 

def find_floor_hints(self): 
    hint_ids = set() 
    print("Finding hints in file") 
    for hint in self.f_soup.find_all('hint'): 
     hint_ids.add(hint.localization.string) 
    return hint_ids 

我使用創建對象並調用方法的代碼的相關部分:

for q in questSoup.find_all('quest'): 
gc.collect() 
ql = find_q_line(q) 
floors = set() 
for f in set(q.find_all('location_id')): 
    if f.string not in skip_loc: 
     floor_soup = FloorSoup(f.string) 
     join_dict(string_by_ql, ql, floor_soup.find_floor_npcs()) 
     join_dict(string_by_ql, ql, floor_soup.find_floor_hints()) 
     del floor_soup 
    else: 
     print("Skipping location " + f.string) 

通過將find_floor_hints方法進行使用,我是能夠幾乎完全移除內存泄漏(或到其影響可忽略不計的地步)。因此我懷疑這個問題可能在於這個特定的方法。

任何幫助將不勝感激!

回答

1

引用this answer,我能夠通過使用

hint_ids.add(str(hint.localization.contents)) 

好像前者返回的通航字符串卸下find_floor_hints方法泄漏,這似乎留下一些(讀:一個可怕的很多)即使在刪除了FloorSoup對象之後也會引用它。我不確定它是一個錯誤還是一個功能,但它是有效的。