2

我正在解析 ~250K XMLs 并将数据加载到 SQLite 数据库中。我在具有 8GB 内存的 Mac OS X 笔记本电脑上cheerio使用节点版本 10.15.1。better-sqlite3我正在readdirSync处理约 250K 文件的整个文件夹,并解析 XML 文件并使用 10K 批次的事务加载提取的数据。我正在使用--max_old_space_size=4096但仍然收到FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory

现在,如果我处理 100K 文件,然后退出节点,然后重新启动并处理剩余的 ~150K 文件,那么一切正常。但是,我宁愿一次性完成,因为这是必须在无人看管的情况下完成的事情。考虑到我的限制,我还能做些什么吗?我无法使用内存更大的机器,因为我无权访问。我可以尝试增加--max_old_space_size一点,或者我可以尝试做小批量的交易,但我不确定这是否会有所帮助(我尝试了每个交易 8000 个文件而不是 10K,但这也耗尽了内存)。现在唯一似乎有帮助的是在两者之间退出节点。反正我可以模拟吗?也就是告诉node释放所有内存,假装重启了?还有其他想法吗?

4

1 回答 1

0

所以,我终于偶然发现了解决问题的方法(我使用“stumbled”,因为我不确定这是否绝对是正确的策略,但它对我有用)。

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

无论如何,用 a 处理 1K 交易--max_old_space_size=2048对我来说已经完成了这项工作。节点的内存使用(如Activity Monitor所示非常稳定,250K 文件的整个转储在大约 42 分钟内被解析并加载到数据库中。我可以忍受。

于 2019-02-19T08:32:50.597 回答