Javascript 需要一种绕过“问题”的方法;“节点内存不足”;错误

Javascript 需要一种绕过“问题”的方法;“节点内存不足”;错误,javascript,node.js,cheerio,better-sqlite3,Javascript,Node.js,Cheerio,Better Sqlite3,我正在解析~250K XML并将数据加载到SQLite数据库中。我在一台具有8GB内存的Mac OS X笔记本电脑上使用的是节点版本10.15.1,带有cheerio和better-sqlite3。我正在readdirSync-ing包含~250K个文件的整个文件夹,解析XML文件,并使用批量为10K的事务加载提取的数据。我正在使用--max\u old\u space\u size=4096,但仍然出现致命错误:堆限制分配附近的无效标记压缩失败-JavaScript堆内存不足 现在,如果我处理

我正在解析~250K XML并将数据加载到SQLite数据库中。我在一台具有8GB内存的Mac OS X笔记本电脑上使用的是节点版本10.15.1,带有
cheerio
better-sqlite3
。我正在
readdirSync
-ing包含~250K个文件的整个文件夹,解析XML文件,并使用批量为10K的事务加载提取的数据。我正在使用
--max\u old\u space\u size=4096
,但仍然出现致命错误:堆限制分配附近的无效标记压缩失败-JavaScript堆内存不足


现在,如果我处理100K个文件,然后退出节点,然后重新启动并处理剩余的~150K个文件,那么一切都正常。但是,我宁愿一次性完成,因为这是一件必须在无人看管的情况下完成的事情。考虑到我的限制,还有什么我能做的吗?我不能使用内存更多的机器,因为我没有访问内存的权限。我可以尝试将
--max\u old\u space\u size
的值提高一点,或者我可以尝试做一些小批量的事务,但我不确定这是否会有帮助(我尝试过每个事务使用8000个文件,而不是10K,但内存也用完了)。现在唯一有帮助的是退出中间的节点。我能模拟一下吗?也就是说,告诉节点释放所有内存并假装它已重新启动?还有其他想法吗?

因此,我终于找到了解决问题的方法(我使用“stumbled”,因为我不确定这是否确实是正确的策略,但它对我有效)

我发现实际上增加
--max\u old\u space\u size
的值并没有真正帮助我。在任何情况下,正如我上面提到的,我的MacBook只有8GB,所以我有一个下限。相反,实际上帮助我的是简单地减少批量大小。因此,我一次处理1K XML,而不是处理10K XML,将它们的数据存储在内存中,然后将它们插入SQLite中的事务中。当然,要处理大约250K个文件,我现在必须处理250个循环,而不是25个循环,但这并没有真正增加我的时间太多。我发现处理时间是非常线性的,大约每1K个文件5公里毫秒(或每10K个文件50公里毫秒)。无论我在事务中向SQLite抛出1K或10K插入,SQLite都非常快,但在处理大量数据时,XML解析器进程会启动。事实上,
cheerio
(我发现这很好)也可能没有任何问题。这可能是我的编码风格,可以改进很多


在任何情况下,用
--max\u old\u space\u size=2048
处理1K事务对我来说都是可行的。节点使用的内存(如Activity Monitor中所示,相当稳定,整个250K文件转储大约在42分钟内被解析并加载到数据库中。我可以接受。

这听起来像是内存泄漏,但如果没有任何示例代码,则很难诊断。Node将自动回收任何未使用的内存。存在som例如,您在如此短的时间内创建了太多的小对象,因此无法进行垃圾收集,并且仍然会耗尽内存。我建议您查看
heapdump
,看看是否存在内存泄漏。我在cheerio和切换到whacko时遇到过类似问题。请小心@pguardiario