我有一个带有捆绑程序的 Rails 2.3.10 应用程序。启动时内存占用非常大(开发模式下为 300MB)。
我想看看每个 gem 在启动时占用多少内存。
我有一个带有捆绑程序的 Rails 2.3.10 应用程序。启动时内存占用非常大(开发模式下为 300MB)。
我想看看每个 gem 在启动时占用多少内存。
我们遇到了一个问题,即没有流量或请求的基本 Rails 应用程序在启动时的占用空间约为 140MB。
我们使用以下方法来跟踪我们应用程序的 Gemfile 中指定的每个 gem 的内存需求,而无需尝试修补 bundler。
rails new myappname
生成一个新的空 Rails 应用程序bundle install
,然后rails server
确保可以启动 rails 服务器并加载所需的任何基本配置require: false
在每一行的末尾追加。确保使用一个名称指定但需要使用 :require => 'othergemname' 的任何其他 gem 使用较旧的 ruby 哈希表示法,以便下面的模式匹配将捕获它。bundle install
以重新生成 Gemfile.lock创建以下脚本,该脚本将手动使用 Gemfile 中指定的每个 gem,并记录 rails 进程之前和之后消耗的系统内存。
# require_and_profile.rb
def require_and_profile(gemname = nil)
unless gemname
puts "%-20s: %10s | %10s" % ['gem','increment','total']
return
end
# This is how to get memory of calling process in OS X, check host OS for variants
memory_usage = `ps -o rss= -p #{Process.pid}`.to_i / 1024.0
require gemname
puts "%-20s: %10.2f | %10.2f" % [ gemname, (`ps -o rss= -p #{Process.pid}`.to_i / 1024.0 - memory_usage), (`ps -o rss= -p #{Process.pid}`.to_i / 1024.0)]
end
pattern = /^[^#]*gem[ ]*['"]([^,'"]*)['"][ ,~>0-9\.'"]*(:require[ => ]*['"]([^'"]*)['"][, ])?/
require_and_profile
File.open('Gemfile').each do |line|
if line.match(pattern)
if line.match(pattern)[3]
require_and_profile line.match(pattern)[3]
else
require_and_profile line.match(pattern)[1]
end
end
end
跑rails c
load 'require_and_profile.rb'
例如,这有助于我们确定,当我们只在 :asset 组中需要它时,我们一直在启动时需要资产同步。我们确实发现,在不同的启动过程中,每个 gem 的内存占用并不完全相同,但运行几次确实会向您显示哪些是需要内存的 gem 的模式。
现在使用 derailed gem 有一种更简单的方法:
添加到您的gemfile:
gem 'derailed', group: :development
然后在您的应用程序根目录的命令行上:
bundle exec derailed bundle:mem
这将打印出每个 gem 包含多少内存。
我会这样做:
c = 0; ObjectSpace.each_object { c += 1 }
)通过这种方式,您将看到哪个 gem 导致实例化的对象最多,因此间接导致最多的内存使用。
不过有两个警告: