ruby 中的间歇性 NoMemoryError

Intermittent NoMemoryError in ruby

我们有一个 Ruby rails 运行ner 脚本加载一堆 JSON 模式文件,处理它们,并将处理后的数据写入文件。

如果我 运行 rails 运行ner 脚本重复,它会引发 分配内存失败 (NoMemoryError) 每 15- 20次。我比较了终止前失败和成功 运行 之间的内存使用情况,两者均为 ~178 MB。 VM 大约有 ~ 2 GB 的可用内存。

根据我为调试添加的日志行,当代码执行 JSON.pretty_generate(schema).

时失败

观察:

  1. 脚本正在处理同一组文件,我不明白为什么它会间歇性地引发 NoMemoryError
  2. 脚本正在以相同的顺序处理文件
  3. 在所有失败的 运行 中,它恰好在处理特定文件时失败。我启动了 IRB 并尝试对文件执行相同的一组操作,并测量这些操作前后的内存使用情况。它导致内存仅增加 ~100 KB。
  4. 我尝试提高 RUBY_GC_HEAP_INIT_SLOTS,这样进程内存大小是成功或失败 运行 的 10 倍,但仍然没有运气。当它引发 NoMemoryError
  5. 时,有很多 heap_free_slots (54x heap_live_slots)

以下是我的问题:

  1. 即使 VM 中有大约 ~2GB 的可用内存,为什么 Ruby 没有分配更多内存?
  2. 有任何指示或建议吗?

Ruby版本:2.7.1 Rails版本:5.2.4.2

谢谢!

我们将范围缩小到 Oj gem。以下提交修复了该问题。

https://github.com/ohler55/oj/commit/f026333afed8c3ecda4978d41914dd5a424cb995#diff-99f7fc0c2799095139bbbfb7b553ce81c0c6edcbc3b2f6b729bb26d052b8ed6d