我正在解析约25万个XML,并将数据加载到SQLite数据库中。我在具有8GB内存的Mac OS X笔记本电脑上使用带有cheerio
和better-sqlite3
的节点版本10.15.1。我正在readdirSync
-访问约250K文件的整个文件夹,并使用10K的批量交易解析XML文件并加载提取的数据。我正在使用--max_old_space_size=4096
,但仍然出现致命错误:接近堆限制的无效标记压缩-分配失败-JavaScript堆内存不足。
现在,如果我处理10万个文件,然后退出节点,然后再次启动并处理剩余的约150K个文件,那么一切正常。但是,我宁愿一口气做这件事,因为这是无人值守的事情。考虑到我的限制,我还能做些其他事情吗?我无法使用一台拥有更多内存的计算机,因为我无法访问一台计算机。我可以尝试进一步提高--max_old_space_size
,也可以尝试进行更小批量的交易,但是不确定是否会有所帮助(我尝试每个事务处理8000个文件,而不是10K,但也用光了的内存)。现在似乎唯一有帮助的是退出两者之间的节点。无论如何,我可以模拟吗?也就是说,告诉节点释放所有内存并假装它已重新启动?还有其他想法吗?
答案 0 :(得分:0)
所以,我终于迷失了方向(我使用“迷迷糊糊”,因为我不确定这是否绝对是正确的策略,但是对我有用)。
我发现实际上提高--max_old_space_size
的值并没有真正帮助我。无论如何,如上所述,我的MacBook仅有8GB,因此无论如何我都有一个较低的限制。相当逆势,实际上帮助减少了我的批量大小。因此,我没有处理10K XML,而是将它们的数据存储在内存中,然后将它们插入SQLite中的事务中,而是一次处理了1K XML。当然,要处理约25万个文件,我现在必须处理250个循环而不是25个循环,但这并没有真正增加我的时间。我发现处理时间非常线性,每1K文件大约5K ms(或每10K文件大约50K ms)。无论在事务中向其扔1K还是10K INSERT,SQLite都非常快,但是当处理大量数据时,正是我的XML解析器过程开始起作用。实际上,cheerio
可能也没有任何问题(我发现这很好)。可能只是我的编码风格可以改进很多。
无论如何,用--max_old_space_size=2048
处理一千笔交易对我来说是一件好事。节点的内存使用情况(如活动监视器中所示)非常稳定,并且已解析了整个250K文件转储并将其加载到db中,大约需要42分钟。