Ruby 内存使用变得疯狂

Ruby Memory Usage gone wild

我使用 RestClient 从数据供应商那里下载了大约 75 张图像 + 40 页详细信息。

是这样的:

  1. 验证供应商服务并在变量中设置 cookie jar
  2. 下载XML
  3. XML 包含大约 40 项资产。
  4. 为每个资产下载图像列表。 (每项资产包含 0-10 张图像)。
  5. 下载图片。

通过 115 个独特的请求,我的总下载大小为 148.14Mb,耗时 37.58 秒。我的内存消耗是:

Total allocated: 1165532095 bytes (295682 objects)
Total retained:  43483 bytes (212 objects)

memory_profilergem测量。这只是超过 1GB 的内存来下载 ~150MB 的数据?

我最担心的是,我需要下载更多数据 - 这只是 15 天数据中的 1 天。当我 运行 2 天的数据时,我将下载大小和内存大小加倍。当 运行 宁 3 天的数据我三倍等。它甚至看起来内存消耗呈指数增长,直到我 运行 内存不足并且我的服务器崩溃。

为什么这里没有垃圾收集?我已经尝试 运行宁 GC.start 在我下载的每一天数据之间,这个技巧 memory_profiler,但是当我添加太多天的数据时,我的服务器仍然会崩溃。

所以我的问题是:

  1. 为什么与我实际下载的数据相比,内存消耗如此之高。
  2. 由于我在每次下载之间覆盖保存下载数据的变量,垃圾收集是否应该不清除前一次数据下载的内存?
  3. 有什么技巧可以降低内存消耗吗?

版本: Ruby:2.4.4p296,RestClient:2.0.2, OS: Ubuntu 16.04

示例代码:

使用 RestClient:https://gist.github.com/mtrolle/96f55822122ecabd3cc46190a6dc18a5

使用 HTTParty:https://gist.github.com/mtrolle/dbd2cdf70f77a83b4178971aa79b6292

谢谢

我相信这与您使用的 http 客户端有关:Rest-Client。不幸的是,它有一些内存饥饿的坏名声。你绝对应该寻找一些很棒的 gem,它既 memory/time 高效 .

我强烈推荐HTTP.rb or its http/2 successor HTTPX

要获得良好的基准,请查看另一篇很棒的文章 gem Shrine: https://twin.github.io/httprb-is-great/

作者的这篇很棒的文章

这是我在本地机器上用 HTTP.rb 替换 Rest-Client 后发现的:

版本:Ruby:2.5.3p105,HTTP.rb:4.0.0,OS:Ubuntu16.04

总下载大小:96.92Mb 通过 118 个唯一请求。

内存消耗:

Total allocated: 7107283 bytes (83437 objects)
Total retained:  44221 bytes (385 objects)

所以它只分配了 7Mb 而下载 96.92Mb 与使用 Rest-Client 大约 1Gb 相比。

这是片段:https://gist.github.com/mtrolle/96f55822122ecabd3cc46190a6dc18a5#gistcomment-2774405