rspec - 是什么让 Rspec 占用 4gb 的内存来运行 500 个规范?
问题描述
当我在本地机器上运行这些规范时,我正在开发一个具有 500 多个规范的应用程序,它成功通过了。但是当这些规范在 CircleCI 上运行时,该进程被终止。我试图通过跟踪本地计算机上的内存来调查问题。当我看到 ruby 进程占用 4gb 内存时,我感到很惊讶,这就是触发 CircleCI 杀死进程的原因。
我不确定我的规范占用所有这些内存的原因,我已经搜索了在每个规范之后清理内存但无济于事的配置。
这是我的rails_helper.rb
require "mongoid-rspec"
require "spec_helper"
ENV["RAILS_ENV"] ||= "test"
require File.expand_path("../../config/environment", __FILE__)
if Rails.env.production?
abort("The Rails environment is running in production mode!")
end
require "database_cleaner"
require "rspec/rails"
#
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
RSpec.configure do |config|
config.infer_spec_type_from_file_location!
# FactoryGirl
config.include FactoryGirl::Syntax::Methods
# Render
config.render_views
# Filter lines from Rails gems in backtraces.
config.filter_rails_from_backtrace!
# arbitrary gems may also be filtered via:
# config.filter_gems_from_backtrace("gem name")
config.include Mongoid::Matchers, type: :model
config.include Requests::JSONHelpers, type: :request
config.include Requests::AuthHelpers, type: :request
config.include Requests::JSONHelpers, type: :controller
config.include Requests::AuthHelpers, type: :controller
config.before(:suite) do
DatabaseCleaner.orm = "mongoid"
DatabaseCleaner.strategy = :truncation, { except: %w[roles] }
DatabaseCleaner.clean_with(:truncation)
Rails.application.load_seed # loading seeds
end
config.around(:each) do |example|
DatabaseCleaner.cleaning do
example.run
end
end
config.after(:suite) do
DatabaseCleaner.strategy = :truncation
DatabaseCleaner.clean
end
end
这是我的spec_helper.rb
require "mongoid-rspec"
require "webmock/rspec"
require "pundit/rspec"
require "excon"
WebMock.disable_net_connect!(allow_localhost: true)
RSpec::Matchers.define :match_response_schema do |schema|
match do
schema_directory = "#{Dir.pwd}/spec/schemas"
schema_path = "#{schema_directory}/#{schema}.json"
JSON::Validator.validate!(schema_path, parsed_json, strict: true)
end
end
RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
config.shared_context_metadata_behavior = :apply_to_host_groups
config.include Mongoid::Matchers
config.before(:all) do
Excon.defaults[:mock] = true
Excon.stub({}, body: "{}", status: 200)
end
end
更新:我在每个示例之后启动垃圾收集器来修复它
在rails_helper.rb
config.after(:each) do |example|
GC.start
end
但是,我希望找到比这更好的解决方案
解决方案
有帮助的事实GC.start
表明这不是内存泄漏。也许你有一些古怪的 GC 设置。如果是这样 - 尝试一些调整:https ://blog.evanweaver.com/2009/04/09/ruby-gc-tuning/
[在我意识到你的问题可能不是那个之前,我写了内存泄漏搜索部分,但我会留下它,因为它可能对某些人有用]
我要做的是运行分析ruby-prof
,将其设置为收集 MEMORY 统计信息
这是和示例:
require 'ruby-prof'
RubyProf.measure_mode = RubyProf::ALLOCATIONS
result = RubyProf.profile(:track_allocations => true) do
100.times { rand(1) ? "*" * rand(100) : 20* rand(100) }
end
printer = RubyProf::GraphHtmlPrinter.new(result)
printer.print(File.new("/tmp/report.html", "w+"))
报告看起来有点像这样 [![在此处输入图像描述][1]][1]
所以,你需要做的是这样的:
around(:suite) do |suite|
require 'ruby-prof'
RubyProf.measure_mode = RubyProf::ALLOCATIONS
result = RubyProf.profile(:track_allocations => true) do
suite.run
end
printer = RubyProf::GraphHtmlPrinter.new(result)
printer.print(File.new("/tmp/report.html", "w+"))
end
也许您将能够找到哪些对象被过度表示,并且从那里您可能会发现泄漏。尝试使用不同mearure_mode
的 s 和打印机以获得更好的视角。[1]:https ://i.stack.imgur.com/2ZFcO.png
推荐阅读
- r - 分组数据框 - 分组为 ggplot 中的方面?
- javascript - 如何更改数组中最后一个元素的颜色 - js
- lua - Lua PerformIngameSpawn,世界服务器重启后生成的生物
- javascript - 在 Shopify 中截断产品系列描述文本
- python - 将带有时区的时间日期字符串转换为utc python
- sql - 提取两个字符之间的某些文本
- python - 需要帮助使用 pygame 旋转矩形
- postgresql - 如何在 go 的 gorm 模型中访问每个字段需要映射到的 postgres 类型?
- split - 将 JSON“字典”拆分为单独的行
- java - 在运行时将 SQS 队列动态修改为 @SqsListener 方法?