1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
# frozen_string_literal: true
require_relative 'ruby_object_leak_tracker'
require_relative 'os_memory_leak_tracker'
module MemoryTestHelpers
class << self
attr_accessor :gc_proc, :iterations, :logger
def setup
if RUBY_PLATFORM == "java"
# for leak detection
JRuby.objectspace = true if defined?(JRuby)
# for gc
require 'java'
java_import 'java.lang.System'
self.gc_proc = proc { System.gc }
else
self.gc_proc = proc { GC.start }
end
end
end
module TestMethods
def memory_leak_test(description, &block)
context(description) do
it "doesn't leak ruby objects" do
object_leak_tracker = RubyObjectLeakTracker.new
track_memory_usage(object_leak_tracker, &block)
object_leak_tracker.total_difference_between_runs.should be <= 10
end
it "doesn't leak OS memory (C interop check)" do
os_memory_leak_tracker = OSMemoryLeakTracker.new
track_memory_usage(os_memory_leak_tracker, &block)
os_memory_leak_tracker.total_difference_between_runs.should be <= 10
end
end
end
end
def track_memory_usage(tracker)
# Intentionally do all this setup before we do any testing
logger = MemoryTestHelpers.logger
iterations = MemoryTestHelpers.iterations
checkpoint_frequency = (iterations / 10.0).to_i
gc_frequency = 20
warmup_iterations = [(iterations / 3.0).to_i, 500].min
logger.info "Performing #{warmup_iterations} warmup iterations"
warmup_iterations.times do
yield
MemoryTestHelpers.gc_proc.call
end
tracker.capture_initial_memory_usage
logger.info "Performing #{iterations} iterations (checkpoint every #{checkpoint_frequency})"
iterations.times do |i|
yield
last_iteration = (i == iterations - 1)
checkpoint = last_iteration || (i % checkpoint_frequency == 0)
if checkpoint || (i % gc_frequency == 0)
MemoryTestHelpers.gc_proc.call
end
if checkpoint
logger.info "Iteration #{i} checkpoint"
tracker.capture_memory_usage
tracker.dump_status(logger)
end
end
end
end
|