我遇到了内存错误,我正在尝试为这个问题找到最佳解决方案。基本上我通过同一类的多个线程下载了很多 XML 文件。我的班级使用以下命令下载文件:urlretrieve(link, filePath)我将下载文件的路径保存到线程之间同步的队列中。downloadedFilesQ.put(filePath)在另一个类(也是多个线程)中,我尝试解析这些 XML 文件并将它们保存为 Python 对象,以便将来保存在数据库中。我正在使用以下命令来解析文件: xmldoc = minidom.parse(downloadedFilesQg.get())下载和解析流程同时运行。下载流程在大约 2 分钟后完成,而解析流程大约需要 15 分钟。15 分钟后,我在以下行出现内存错误:Exception in thread XMLConverterToObj-21:Traceback (most recent call last): File "C:\Users\myuser\AppData\Local\Programs\Python\Python37-32\lib\threading.py", line 926, in _bootstrap_inner self.run() File "C:\Users\myuser\AppData\Local\Programs\Python\Python37-32\lib\threading.py", line 870, in run self._target(*self._args, **self._kwargs) File "C:\Users\myuser\PycharmProjects\weat\Parsers\ParseXML.py", line 77, in parseXML xmldoc = minidom.parse(xml_file) File "C:\Users\myuser\AppData\Local\Programs\Python\Python37-32\lib\xml\dom\minidom.py", line 1958, in parse return expatbuilder.parse(file) File "C:\Users\myuser\AppData\Local\Programs\Python\Python37-32\lib\xml\dom\expatbuilder.py", line 911, in parse result = builder.parseFile(fp) File "C:\Users\myuser\AppData\Local\Programs\Python\Python37-32\lib\xml\dom\expatbuilder.py", line 207, in parseFile parser.Parse(buffer, 0) File "c:\_work\16\s\modules\pyexpat.c", line 417, in StartElement File "C:\Users\myuser\AppData\Local\Programs\Python\Python37-32\lib\xml\dom\expatbuilder.py", line 746, in start_element_handler _append_child(self.curNode, node) File "C:\Users\myuser\AppData\Local\Programs\Python\Python37-32\lib\xml\dom\minidom.py", line 291, in _append_child childNodes.append(node)MemoryError我考虑的选项是,一旦我达到 100K python 对象,将它们保存到数据库,然后再次继续解析。问题是多个业务可以重复,因此我想解析一次所有文件,然后将业务插入到一个集合中(以忽略重复的业务)。我还有其他可以尝试的方法吗?
1 回答
慕田峪4524236
TA贡献1875条经验 获得超5个赞
您似乎同时将所有内容都保存在内存中。然而,计算机使用的内存 RAM 比存储内存(硬盘)要有限得多。因此,您可以轻松地在存储器中存储大量 XML 文档,但不能同时在 RAM 中保存所有内容。
在你的情况下,这意味着你应该从根本上改变你的程序。
您的程序应该以流方式工作,这意味着它应该加载一个 XML 文档,对其进行解析,以某种方式对其进行处理,将其结果存储在数据库中,然后再次忘记该文档。最后一点对于释放文档占用的 RAM 至关重要。
现在您写道,您需要弄清楚哪些文档是重复的。
为了实现这一点,我建议不要将整个文档存储在内存中,而只是为每个文档存储一个哈希值。为此,您需要提供一个像样的散列函数,为给定的文档创建一个唯一的散列值。然后你只将你处理的每个文档的哈希值存储在 aset
中,每次遇到具有相同哈希值的新文档时,你就会知道这是一个重复的文档并可以相应地处理它(例如忽略它)。
虽然在内存中同时保存 7000 个 9MB 大小的文档可能是不可能的,但在内存中同时保存 7000 个哈希值是很容易的。
添加回答
举报
0/150
提交
取消