让每个mongrel节约100M内存

最近aaron发表了一篇博客: 让每个mongrel节约100M内存,我觉得值得翻译一下。

---翻译开始的分割线---
我们注意到运行一个rails应用的mongrel在一启动就使用了244M内存
PID USER            PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
53749 some_user     15   0  337m 244m 2912 S    0  2.0   0:17.49 mongrel_rails


通过运行 Bleakhouse(一个用于检测ruby内存泄漏的工具),我们发现有超过200,000个对象被创建了出来:
$ BLEAK_HOUSE=1 ruby-bleak-house ./script/runner 'puts 1'
** Bleakhouse: installed
1
** BleakHouse: working...
** BleakHouse: complete
** Bleakhouse: Run 'bleak /tmp/bleak.53749.0.dump' to analyze.

$ bleak /tmp/bleak.53749.0.dump 
Displaying top 20 most common line/class pairs
2,047,025 total objects
2,047,025 filled heap slots
2,403,764 free heap slots
1779063 __null__:__null__:__node__
197423 __null__:__null__:String
16519 __null__:__null__:Array
12728 __null__:__null__:ActionController::Routing::DividerSegment
10495 __null__:__null__:Hash
5676 __null__:__null__:ActionController::Routing::StaticSegment
5436 __null__:__null__:Class
5132 __null__:__null__:Regexp
4525 __null__:__null__:ActionController::Routing::DynamicSegment
2524 __null__:__null__:ActionController::Routing::Route
1307 __null__:__null__:Gem::Version


可以看到其中有非常多的对象是ActionController::Routing,于是我使用了一个空白的routes.rb,结果:
519,307 total objects
519,307 filled heap slots
233,503 free heap slots


啊哈...有150,000个对象是因为route造成的,我知道我们的应用有很多restful/nested resource,但是没有想到它是如此的疯狂:
$ rake routes | wc -l
2516


通过进一步的观察,我发现可能是由于每个resource会生成formatted_*这样的route,其实我们的应用中很少使用这些route,于是作了个monkey patch:
ActionController::Routing::RouteSet::Mapper.class_eval do 
protected

  def map_unnamed_routes(map, path_without_format, options)
    map.connect(path_without_format, options)
    #map.connect("#{path_without_format}.:format", options)
  end

  def map_named_routes(map, name, path_without_format, options)
    map.named_route(name, path_without_format, options)
    #map.named_route("formatted_#{name}", "#{path_without_format}.:format", options)
  end
end


原先应用中使用到部分的formatted_* route用手工添加,现在通过bleakhouse,发现少创建了80,000个对象:
$ bleak /tmp/bleak.56554.0.dump 
1,242,796 total objects
1,242,796 filled heap slots
1,224,309 free heap slots


内存从244m 下降到了 156m
PID USER            PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
56554 someuser     15   0  249m 156m 2912 S    0  1.3   0:09.92 mongrel_rails


这不是一个很简洁的解决方法,但是它让每个mongrel节约了100M内存,并且启动时间减少了50%

你的Rails应用是否也有那么多的resource?是否也有内存使用过多的问题?试试看这个解决方法把。

---翻译结束的分割线---


从这篇文章我们可以学到如何用bleakhouse检查内存泄漏,以及一些试验方法,不过routes如此耗费内存倒是让我觉得非常吃惊,准备在JavaEye上也试验看看。
另外针对生成大量的route,rails的issue tracker上已经有了一个补丁,让actions和formatted变成可选项:
http://rails.lighthouseapp.com/projects/8994/tickets/1215-add-actions-and-formatted-options-to-mapresources
预计将会在下一版本加入rails

你可能感兴趣的:(Blog,Ruby,Rails)