2017-03-05 151 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对象之后也会引用它。我不确定它是一个错误还是一个功能,但它是有效的。