ruby - Ruby 内存使用变得疯狂
问题描述
我从一个数据供应商那里下载了大约 75 张图片 + 40 页的详细信息,我使用 RestClient 完成了一项工作。
像这样:
- 向供应商服务进行身份验证并在变量中设置 cookie jar
- 下载 XML
- XML 包含大约 40 个资产。
- 对于图像的每个资产下载列表。(每个资产包含 0-10 张图片)。
- 下载图片。
通过 115 个唯一请求,我在 37.58 秒内的总下载大小为 148.14Mb。我的内存消耗是:
Total allocated: 1165532095 bytes (295682 objects)
Total retained: 43483 bytes (212 objects)
用memory_profiler
宝石测量。下载大约 150mb 的数据需要 1gb 以上的内存?
我最担心的是,我需要下载更多数据——这只是 15 天数据中的 1 天。当我运行 2 天的数据时,我将下载大小和内存大小加倍。当运行 3 天的数据时,我增加了三倍等。它甚至看起来内存消耗呈指数增长,直到我用完内存并且我的服务器崩溃。
为什么垃圾收集在这里没有发挥作用?我已经尝试GC.start
在我下载的每一天的数据之间运行,这是技巧memory_profiler
,但是当我添加太多天的数据时,我的服务器仍然最终崩溃。
所以我的问题是:
- 与我实际下载的数据相比,为什么内存消耗如此之高。
- 当我在每次下载之间覆盖保存下载数据的变量时,垃圾收集是否应该不清除以前数据下载的内存?
- 有什么技巧可以降低内存消耗?
版本: Ruby:2.4.4p296,RestClient:2.0.2,操作系统:Ubuntu 16.04
示例代码:
使用 RestClient:https ://gist.github.com/mtrolle/96f55822122ecabd3cc46190a6dc18a5
使用 HTTParty:https ://gist.github.com/mtrolle/dbd2cdf70f77a83b4178971aa79b6292
谢谢
解决方案
我相信这与您正在使用的 http 客户端有关:Rest-Client
. 不幸的是,它有一些内存饥渴的坏名声。您绝对应该寻找一些既节省内存又节省时间的出色宝石。
我强烈推荐HTTP.rb或其 http/2 的继任者HTTPX
要获得一个好的基准,请查看另一个很棒的 gem Shrine的作者的这篇很棒的文章:https ://twin.github.io/httprb-is-great/
这是我在本地机器上用 HTTP.rb 替换 Rest-Client 后发现的:
版本:Ruby:2.5.3p105,HTTP.rb:4.0.0,操作系统:Ubuntu 16.04
总下载大小:96.92Mb ,包含118 个唯一请求。
内存消耗:
Total allocated: 7107283 bytes (83437 objects)
Total retained: 44221 bytes (385 objects)
因此它在下载96.92Mb时仅分配了7Mb ,而使用 Rest-Client 大约为 1Gb。
这是片段:https ://gist.github.com/mtrolle/96f55822122ecabd3cc46190a6dc18a5#gistcomment-2774405
推荐阅读
- sql - 如何在 SQL 中计算使用 CASE 而没有子查询创建的类别的出现次数?
- amazon-s3 - aws python aws中boto和boto3的区别,与S3相关
- javascript - window.matchMedia Javascript 在页面更改时记住用户选择
- java - 如何获得权限 INSTALL_PACKAGE 和 DELETE_PACKAGE?
- docker - 运行 kompose up 时访问被拒绝错误
- python - 我的自定义烧瓶 ValidationError 不起作用
- python-3.x - ImportError:DLL 加载失败:%1 不是有效的 Win32 应用程序 - jupyter notebook 的内核错误
- html - 如何选择和布局的内容不选择
仅使用 CSS
- r - 转向更广泛的同性伴侣
- swift - SwiftUI 持久化可观察对象