diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 059b181bb1c..0df08597bc2 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -37,6 +37,7 @@ include: - local: .gitlab/ci/cng.gitlab-ci.yml - local: .gitlab/ci/docs.gitlab-ci.yml - local: .gitlab/ci/frontend.gitlab-ci.yml + - local: .gitlab/ci/memory.gitlab-ci.yml - local: .gitlab/ci/pages.gitlab-ci.yml - local: .gitlab/ci/qa.gitlab-ci.yml - local: .gitlab/ci/reports.gitlab-ci.yml diff --git a/.gitlab/ci/memory.gitlab-ci.yml b/.gitlab/ci/memory.gitlab-ci.yml new file mode 100644 index 00000000000..50b843df585 --- /dev/null +++ b/.gitlab/ci/memory.gitlab-ci.yml @@ -0,0 +1,19 @@ +memory-static: + extends: .dedicated-no-docs-no-db-pull-cache-job + script: + # Uses two different reports from the 'derailed_benchmars' gem. + + # Loads each of gems in the Gemfile and checks how much memory they consume when they are required. + # 'derailed_benchmarks' internally uses 'get_process_mem' + - scripts/memory-static 'tmp/memory_static_full_report.txt' 'tmp/memory_static_metrics.txt' + + # Outputs detailed information about objects created while gems are loaded. + # 'derailed_benchmarks' internally uses 'memory_profiler' + - scripts/memory-static-objects 'tmp/memory_static_objects_full_report.txt' 'tmp/memory_static_metrics.txt' + artifacts: + paths: + - tmp/memory_static_full_report.txt + - tmp/memory_static_objects_full_report.txt + - tmp/memory_static_metrics.txt + reports: + metrics: tmp/memory_static_metrics.txt diff --git a/scripts/memory-static b/scripts/memory-static new file mode 100755 index 00000000000..54f147a7a91 --- /dev/null +++ b/scripts/memory-static @@ -0,0 +1,20 @@ +#!/usr/bin/env ruby + +require_relative '../lib/gitlab/popen' + +full_report_filename, metrics_filename = ARGV +abort 'usage: memory-static ' unless full_report_filename && metrics_filename + +full_report, status = Gitlab::Popen.popen(%w(bundle exec derailed bundle:mem)) +abort 'failed to execute the benchmark' unless status.zero? + +File.open(full_report_filename, 'w') do |f| + f.write(full_report) +end + +stats = /TOP: (?.*) MiB/.match(full_report.lines.first) +abort 'failed to process the benchmark output' unless stats + +File.open(metrics_filename, 'a') do |f| + f.puts "memory_static_total_mb #{stats[:total_mibs_str].to_f.round(1)}" +end diff --git a/scripts/memory-static-objects b/scripts/memory-static-objects new file mode 100755 index 00000000000..2ad38d9717c --- /dev/null +++ b/scripts/memory-static-objects @@ -0,0 +1,27 @@ +#!/usr/bin/env ruby + +require_relative '../lib/gitlab/popen' + +full_report_filename, metrics_filename = ARGV +abort 'usage: memory-static-objects ' unless full_report_filename && metrics_filename + +full_report, status = Gitlab::Popen.popen(%w(bundle exec derailed bundle:objects)) +abort 'failed to execute the benchmark' unless status.zero? + +File.open(full_report_filename, 'w') do |f| + f.write(full_report) +end + +allocated_str = full_report.lines[1] +retained_str = full_report.lines[2] +allocated_stats = /Total allocated: (?.*) bytes \((?.*) objects\)/.match(allocated_str) +retained_stats = /Total retained: (?.*) bytes \((?.*) objects\)/.match(retained_str) + +abort 'failed to process the benchmark output' unless allocated_stats && retained_stats + +File.open(metrics_filename, 'a') do |f| + f.puts "memory_static_objects_allocated_mb #{(allocated_stats[:bytes].to_f / (1024 * 1024)).round(1)}" + f.puts "memory_static_objects_retained_mb #{(retained_stats[:bytes].to_f / (104 * 1024)).round(1)}" + f.puts "memory_static_objects_allocated_items #{allocated_stats[:objects]}" + f.puts "memory_static_objects_retained_items #{retained_stats[:objects]}" +end