最近发现服务器上的 8G 内存几乎被用尽,newrelic 显示 ruby 进程一共用了 4.58 个 G
某一个使用率比较高的进程占了 2 个多 G:
本地测试的时候发现每次刷新页面获取数据的时候(业务是一次性把当前用户有关数据全部获取)也是 ruby 进程占用内存几 M 的增加
是内存泄露吗 还是缓存了数据了?
求大神指点@Rei
环境:ruby on sinatra,nginx + thin
#4 楼 @jimrokliu 目前情况来看 内存占用一直保持 4 个多 G 无宕机 有可能是 orm 的原因,接下来如你所建议的 就要防止内存泄露了 哈哈 多谢
一个进程 2 个 G, 别的都没事,怎么可能是 ActiveRecord 或者 MongoMapper 的原因。再说这么成熟的库,要有这样的 bug, 早就一堆人跳起来了。
认真排查吧,看看这个进程跟别的有什么区别,然后再排除、假设、试验。
@pynix 要挂了才知道原因就没法做优化了。
我之前做过类似的排查,也是内存占用稳定攀升。我的做法是,开一个临时 branch, controller action 结束时查询内存占用(可以调用 shell script),加入 response(用了一个临时的 header)。
然后做一个 rake task,循环调用该 API, 打印内存占用结果。成功重现内存稳定攀升的 pattern 之后就是一个很好的开端了。
后来一步步排查,遇到可疑的代码就替换或暂时去掉。最后的结果是render file: ..
有问题,内存不能去掉。其他团队定期在这里拿准备好的 JSON 文件,之前很小的文件不觉得,后来文件越来越大,造成内存攀升明显。摸索着改为 send_file 后一切正常,再大的文件都不是问题了。
直接用上 rack-mini_profiler 帮你查询每个请求中内存的使用量,还有 ruby 的很多默认库比如 net/http 有不释放文件缓存的问题。
#17 楼 @huacnlee 由于项目不是 rails 框架 没有 gemfile,也是无经验并没有做记录,现在只能提供 gem list: *** LOCAL GEMS ***
activemodel (4.2.3, 4.1.4) activesupport (4.2.3, 4.1.4) addressable (2.3.8, 2.3.6) autoparse (0.3.3) aws-sdk (1.46.0) aws-sdk-core (2.1.13) aws-sdk-resources (2.1.13) backports (3.6.6, 3.6.0) bigdecimal (1.2.7, 1.1.0) bson (1.10.2) bson_ext (1.10.2) builder (3.2.2) bundler (1.10.6, 1.6.2) bundler-unload (1.0.2) daemons (1.2.3, 1.1.9) eventmachine (1.0.8, 1.0.3) executable-hooks (1.3.2) extlib (0.9.16) faraday (0.9.1, 0.9.0) gearman-ruby (4.0.5, 3.0.7) gem-wrappers (1.2.7, 1.2.4) google-api-client (0.8.6, 0.7.1) googleauth (0.4.2) i18n (0.7.0, 0.6.9) io-console (0.4.2, 0.3) jmespath (1.0.2) json (1.8.3, 1.8.1, 1.5.5) jwt (1.5.1, 1.0.0) launchy (2.4.3, 2.4.2) little-plugger (1.1.3) logging (2.0.0) mailfactory (1.4.0) memoist (0.12.0) mime-types (2.6.1, 2.3) mini_portile (0.6.2, 0.6.0) minitest (5.8.0, 5.3.5, 2.5.1) mongo (1.10.2) mongo_mapper (0.13.1, 0.13.0) multi_json (1.11.2, 1.10.1) multipart-post (2.0.0) nokogiri (1.6.6.2, 1.6.3.rc3) plucky (0.6.6) r18n-core (1.1.11) rack (1.6.4, 1.5.2) rack-protection (1.5.3) rack-test (0.6.3, 0.6.2) rake (10.4.2, 0.9.2.2) rdoc (4.2.0, 3.9.5) retriable (2.0.2, 1.4.1) rubygems-bundler (1.4.4) rufus-scheduler (3.1.3, 3.0.8) rvm (1.11.3.9) signet (0.6.1, 0.5.1) sinatra (1.4.5) sinatra-contrib (1.4.6, 1.4.2) sinatra-r18n (1.1.11) thin (1.6.2) thor (0.19.1) thread_safe (0.3.5, 0.3.4) tilt (2.0.1, 1.4.1) tzinfo (1.2.2, 1.2.1) uuidtools (2.1.5, 2.1.4) 这是服务器上的,ruby 版本 ruby 1.9.3p547,不久前被别人 gem update 了 所以更新了很多包 这也是纠结的地方。
几个建议:
............ 你发你系统的 Gem 我无法看出问题,没有 Gemfile,你居然没用 Bundler ... 请用上,固定好适合项目的 Gem 版本,尝试跑一天看看
MongoMapper 在用么?这货已经一年没更新了,如果可以,建议换成 Mongoid
上面只是一些建议,和你的 Memory leak 无关,你需要告诉我详细情况,最好是能看到代码,才能发现问题。
@jasonshl 为了便于后面其他人参考,这里回复问题
$connections = []
before do
$connections << request
end
after do
$connections.delete(request)
end
你确定任何时候 request 都能清掉?如果不能这里就是泄露的最大隐患
顺便说一句,如果技术能力不够,请用 Rails,不要用 Sinatra 之类的简单框架,你们项目的问题不是一点点。
export.rb 里面那么多类变量是为何?为何不用实例变量?
@@form_name = form.name
@@fields = form.current.fields
@@table_fields = Array.new