Ruby 2.0引入了一个写时拷贝友好的垃圾收集器.我的进程似乎不会让内存共享超过几分钟——它似乎从

还有一些人成功地实现了这一点:

这个程序可以用来判断Linux:https://gist.github.com/kenn/5105061上的内存状态

我的独角兽配置:https://gist.github.com/inspire22/f82c77c0a465f1945305

出于某种原因,我的独角兽应用程序(也带有preload_app=true)的共享内存要少得多.Ruby 2.0-p195、rails 3.2、linux 2.6.18(centos)

[root@thorn script]# ruby memstats.rb 4946
Process:             4946
Command Line:        unicorn_rails worker[4] -c /u/apps/newap/current/lib/unicorn.rb -E production -D
Memory Summary:
  private_clean                   0 kB
  private_dirty              56,324 kB
  pss                        60,256 kB
  rss                        83,628 kB
  shared_clean                4,204 kB
  shared_dirty               23,100 kB
  size                      108,156 kB
  swap                           68 kB 

如果我完全关闭主进程(而不仅仅是HUP),然后重新启动它,并在任何请求排队之前立即判断工作进程,我会得到一个更好的故事:

[root@thorn script]# ruby memstats.rb 5743
Process:             5743
Command Line:        unicorn_rails worker[4] -c /u/apps/newap/current/lib/unicorn.rb -E production -D
Memory Summary:
  private_clean                   0 kB
  private_dirty              21,572 kB
  pss                        27,735 kB
  rss                        66,296 kB
  shared_clean                2,484 kB
  shared_dirty               42,240 kB
  size                       91,768 kB
  swap                            0 kB

但在启动后的5秒钟内,它们又回到了约20MB的共享_clean+共享_dirty.

我怀疑是交换造成了问题,但在降低交换性并确保父进程和子进程都没有被交换(使用swapstats.rb)之后,问题仍然存在.

我不明白什么是共享脏内存,以及它是如何变成私有内存的.我也很想得到一些建议,以提高我的生命周期 和共享记忆量.谢谢

推荐答案

根据你可能已经看到的this answer,有一行是这样的:

请注意,"可共享"页面被视为私有映射,直到

我要做的是测试您是否获得了outlined in this article个好处,将一个10MB的xml文件作为文本字符串直接放入源代码中.然后,如果你启动了20个工作进程,你将能够看到你是否使用了200MB的内存,或者仅仅是10MB,正如新的垃圾收集功能所预期的那样.

UPDATE:

我翻阅了the unicorn source页,找到了this wonderful article页.

总之,它指出,为了使应用程序能够利用Ruby Enterprise Edition的易写易拷贝垃圾收集器,您必须使用set GC.copy_on_write_friendly to true before you fork.

if GC.respond_to?(:copy_on_write_friendly=)
    GC.copy_on_write_friendly = true
end

根据您提供的unicorn配置文件,它似乎缺少分配.

此外,我还喜欢阅读以下相关文章:

根据fork man page人的说法:

在Linux下,fork()是使用copy-on-write页实现的,因此

Since version 2.3.3,而不是调用内核的fork()系统

根据clone man page条:

与fork(2)不同,这些调用允许子进程共享

所以,我读这篇文章的意思是:linux的fork copy on write是unicorn实现内存共享所依赖的功能,直到libc 2.2.3才实现(如果我的解释有误,请有人纠正我).

要判断正在运行的libc版本,可以键入:

ldd --version

或者,找到glibc并直接运行它.在我的系统中,它在以下位置找到了该文件:

locate libc.so
/lib/x86_64-linux-gnu/libc.so.6

Ruby-on-rails相关问答推荐

在has_many关系中由两个条件 Select

我try 使用Ruby on Rails7创建一个Carbon 足迹计算器.但我无法保存和用户S对象

Rails:has_many 通过不返回结果

为什么 Rails 执行器不能识别内核的改进?

将日期时间转换为月、日和年?

Rails 路由到唯一索引

Rails 3 远程表单:如何指定内容类型?

rails, activerecord, 获取当前连接规范

从 ActiveRecord 模型的集合中构建哈希

Django 还是 Ruby-On-Rails?

如何为模型添加属性?

是否可以设置 travis 来运行多种语言的测试?

Rails 3.1 中的 Rails.cache 错误 - TypeError: can't dump hash with default proc

Heroku - 在浏览器中显示当前提交的哈希

长期运行项目中的 Rebase Rails 迁移

ActiveModel::MissingAttributeError:无法使用 FactoryGirl 写入未知属性ad_id

ruby on rails 如何处理 NaN

如何为 Rails 控制器添加延迟以进行测试?

rails 3,如何在 Settings.yml 文件中使用 ENV 配置变量?

我如何为 Rails3/Bundler 供应 gems