ruby - 为什么 Ruby 只是偶尔释放内存?

标签 ruby memory-leaks

根据我生成字符串的方式,Ruby 会向操作系统释放内存,也可能不会。第一个测试代码会占用大约235MB

size = 2**22
string = '!@#$%^&*()-+~`a1234567890abcdefghijklmnopqrstuvwxyz' * size
puts 'Sleeping...'
sleep(5)
string = nil
GC.start
puts 'Just sitting here..'
gets.chomp

调用GC.start 后,测试使用的内存将缩减至几千字节。但是,如果我使用 string = (0...size).map { (65 + rand(26)).chr }.join 运行相同的测试,内存将飙升至 250MB 并且内存使用调用 GC.start 后实际上会增加到 290MB。

编辑:我正在使用 Ruby 1.9.3-p448,因为我正在处理的项目需要它。虽然我会在 Ruby 2.2 上测试它并返回结果。

编辑 2:在 Ruby 2.1 中运行测试代码(Ruby 2.2 在 RVM 中不可用,我只是想快速运行测试)给出了类似的结果。内存仍然没有降低到合理的状态。它从 234MB BGC(在 GC.start 之前)变为 197MB AGC。注意:内存大小不同,因为我在不同的机器上运行它,但具体大小并不重要,只是相对增加和减少(或不减少)。

最佳答案

Ruby MRI 不会将内存释放回操作系统。

这是我在 OSX 10.10 上看到的 Ruby MRI 2.2,使用典型的 ps -o rss:

  • 使用 * 分配大字符串使用 ~220MB。

  • 使用 map 分配大字符串使用 ~340MB。

在我的系统上,GC.start 不会对 RSS 做任何事情。换句话说,我看到 RAM 使用率保持不变。

值得注意的是, map 使用了大量 RAM:

  • (0...size).map{ '' } 使用 ~300MB。

当我循环你的例子时,一些有趣的事情出现了:

  • 使用 * 分配大字符串继续使用相同的 RAM,即 RSS 没有太大变化。

  • 使用 map 分配的大字符串每次循环增长约 40M。

  • 仅执行 (0...size).map{ '' } 每个循环增长约 40M。

这表明 Ruby map 可能存在与 RAM 相关的问题。这不完全是个问题,因为 Ruby 没有引发 NoMemoryException,但似乎是对 RAM 的非最佳使用。

关于ruby - 为什么 Ruby 只是偶尔释放内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27660966/

相关文章:

android - 对话框 fragment 中的内存泄漏

javascript - 使用 socket.io 的内存泄漏

ruby - Watir Webdriver : Iterating table and storing its content in an array

ruby-on-rails - Rails - 设置 TinyMCE Rails gem 后,文本区域框重新调整大小问题

wpf - 使用WinDbg分析WPF应用程序中OutOfMemoryException的根本原因

c++ - 您如何跟踪应用程序内存泄漏?

iphone - 应用程序导致“泄漏”工具崩溃

ruby-on-rails - 如何使 Rails 3 Assets 的预编译速度更快?

ruby-on-rails - 如何测试 RSpec in Rails 中的 204 响应?

ruby-on-rails - 如何让 Rails 响应基于 header 的 json