Ruby 2.1 与 Ruby 2.0 或 1.9 相比,内存使用量增加

Posted

技术标签:

【中文标题】Ruby 2.1 与 Ruby 2.0 或 1.9 相比,内存使用量增加【英文标题】:Memory usage increase with Ruby 2.1 versus Ruby 2.0 or 1.9 【发布时间】:2015-01-22 00:44:49 【问题描述】:

我最近将 Ruby 从 2.0 升级到 2.1.5 到我的 Heroku Web 应用程序,我现在一直遇到内存配额错误,而在 2.0 和 1.9 中从未发生过这种情况。普通 Heroku Dyno 的限制为 512MB,我正在使用 Unicorn 运行 2 个进程,以及跨两个 dyno 使用 Sidekiq 的一个线程。

阅读Phusion Passenger memory consumption increase from 1.9.3 (system) to 2.1.2 (RVM) on Ubuntu 后,我尝试将环境变量RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR 设置为0.9 以禁用分代垃圾收集器,它确实在一定程度上改善了内存消耗,但仍然让我与2.0 或1.9 的消耗相去甚远。由于现在内存是我最关心的问题,我想看看是否可以使用 ruby​​ 2.1.x 解决这个问题,而不是恢复到 2.0。

以下是一些演示问题的图表:

就在下午 2 点之前,我将 Ruby 2.0.0-p598 降级到 Ruby 2.1.5,内存问题得到了解决,并且仍然在限制之下。

后来,我尝试升级到 Ruby 2.1.5,但将环境变量 RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR 设置为 0.9。如您所见,内存使用情况比原来的 2.1.5 图略好,但仍然超出了内存配额。

【问题讨论】:

非常有趣。我原以为this 是相关的,但很想知道这里的答案是什么。 也一直在关注 2.2 版本,但我担心他们主要关注性能改进而不是内存消耗改进,所以我怀疑它不会有太大帮助。 一些早期测试人员报告由于 2.0.0-preview1 中更新的 GC 导致内存占用减少。您可能想检查一下。 @Lenart,你的意思是 2.2.0-preview1 吗? @MatthewO'Riordan 这是正确的。 2.2 当然。我的错! 【参考方案1】:

这是 Ruby(版本 2.1.x)及其垃圾收集的一个已知问题。在阅读了几个论坛/博客文章之后,似乎没有真正的解决方案,只能执行以下操作之一:

降级到 ruby​​ 2.0 并等待 ruby​​ 2.2 发布 使用 unicorn worker killer 在 unicorn worker 达到一定内存量后重新启动它们,防止 Heroku R14 错误 有人建议调整 GC 变量(请参阅 here 和 here)

这是相关discussion on ruby-lang的链接。

有些人还注意到问题的根源之一可能是 NewRelic 的 gem,因此您可能需要更新/删除它,看看它是否有帮助。

来自 upcase.com 论坛的一些链接和信息的致谢

【讨论】:

关于 NewRelic gem 问题,您可以将 aggressive_keepalive: true 添加到您的配置中。这应该有助于解决由 newrelic gem 引起的内存问题。 感谢@Lenart,这些都是很好的建议。当我遇到这个问题时,我降级到了 2.0,希望 2.2 版本能够解决这个问题,尽管根据我所读到的内容,我并不完全相信它会。我会在 2.2 发布后立即更新这篇文章。 我现在不在,但会在新年尝试并在此处提供更新。 @ari Ruby 2.2 对我来说也有同样的问题 我刚刚升级了我的 gem 并使用 Ruby 2.2 进行了部署,等我让它运行几个小时后,我会提供更新。【参考方案2】:

所以答案显然是升级到 Ruby 2.2 版。

看到升级到 2.2 后内存使用量实际上有所下降,这让我印象深刻,而升级到 2.1 则内存消耗量大幅增加。请参见下图。

在最左侧,2.0 在负载下的内存消耗约为 386mb,而 2.2 现在约为 365mb。

【讨论】:

我也看到了 Ruby 2.2 内存消耗方面的改进。您可能应该将答案标记为正确。 Ruby 2.2 与 Rails 3.2 稳定吗?

以上是关于Ruby 2.1 与 Ruby 2.0 或 1.9 相比,内存使用量增加的主要内容,如果未能解决你的问题,请参考以下文章

与 Ruby 1.9 一起使用的分配跟踪器?

Ruby:字符串在 1.9 中不再混入 Enumerable

我可以在 Ruby 1.9 上设置默认字符串编码吗?

Ruby 1.9 中更自然的 Proc 调用方式

如何使用 ruby​​ 1.9 转换字符编码

ruby 1.9:UTF-8 中的无效字节序列