Use adaptive sampling for memory leak tests

Temporary memory growth caused intermittent failures, while repeated
warmups made these tests slow.
This commit is contained in:
Nobuyoshi Nakada authored and Nobuyoshi Nakada committed 2026-10-19 20:51:56 +09:00
1 parent 18ec10c7f8
commit 0302df2e41
18 files changed
+121 -157
Notes: git 2026-10-19 11:52:31 +00:00

No files matched your search

+9 -7
View File
@@ -1752,7 +1752,7 @@ class TestRipper::ParserEvents < Test::Unit::TestCase
end
def test_return_out_of_compile_error_no_memory_leak
assert_no_memory_leak(%w(-rripper), "#{<<~'begin;'}", "#{<<~'end;'}", rss: true)
assert_no_memory_leak(%w(-rripper), "#{<<~'begin;'}", "#{<<~'end;'}", rss: true, samples: 10..100)
class MyRipper < Ripper
def initialize(src, &blk)
super(src)
@@ -1767,14 +1767,14 @@ class TestRipper::ParserEvents < Test::Unit::TestCase
# Check that call_parse does return a syntax error
raise "call_parse should return a syntax error" unless call_parse
begin;
100_000.times do
1_000.times do
call_parse
end
end;
end
def test_return_out_of_warn_no_memory_leak
assert_no_memory_leak(%w(-rripper), "#{<<~'begin;'}", "#{<<~'end;'}", rss: true)
def test_return_out_of_warn_dup_keys_no_memory_leak
assert_no_memory_leak(%w(-rripper), "#{<<~'begin;'}", "#{<<~'end;'}", rss: true, samples: 10..100)
class MyRipper < Ripper
def initialize(src, &blk)
super(src)
@@ -1789,12 +1789,14 @@ class TestRipper::ParserEvents < Test::Unit::TestCase
# Check that call_parse does warn
raise "call_parse should warn" unless call_parse
begin;
500_000.times do
1_000.times do
call_parse
end
end;
end
assert_no_memory_leak(%w(-rripper), "#{<<~'begin;'}", "#{<<~'end;'}", rss: true)
def test_return_out_of_warn_token_info_no_memory_leak
assert_no_memory_leak(%w(-rripper), "#{<<~'begin;'}", "#{<<~'end;'}", rss: true, samples: 10..100)
class MyRipper < Ripper
def initialize(src, &blk)
super(src)
@@ -1810,7 +1812,7 @@ class TestRipper::ParserEvents < Test::Unit::TestCase
# Check that call_parse does warn
raise "call_parse should warn" unless call_parse
begin;
1_000_000.times do
1_000.times do
call_parse
end
end;
+27 -16
View File
@@ -167,41 +167,52 @@ end
assert_empty(lex)
end
def test_no_memory_leak
assert_no_memory_leak(%w(-rripper), "", "#{<<~'end;'}", rss: true)
2_000_000.times do
def test_empty_no_memory_leak
assert_no_memory_leak(%w(-rripper), "", "#{<<-"{#"}\n#{<<-'};'}", rss: true, samples: 2..100)
{#
1000.times do
Ripper.parse("")
end
end;
};
end
def test_unclosed_class_no_memory_leak
# [Bug #19835]
assert_no_memory_leak(%w(-rripper), "", "#{<<~'end;'}", rss: true)
1_000_000.times do
assert_no_memory_leak(%w(-rripper), "", "#{<<-"{#"}\n#{<<-'};'}", rss: true, samples: 2..100)
{#
1000.times do
Ripper.parse("class Foo")
end
end;
};
end
def test_unclosed_lambda_no_memory_leak
# [Bug #19836]
assert_no_memory_leak(%w(-rripper), "", "#{<<~'end;'}", rss: true)
1_000_000.times do
assert_no_memory_leak(%w(-rripper), "", "#{<<-"{#"}\n#{<<-'};'}", rss: true, samples: 2..100)
{#
1000.times do
Ripper.parse("-> {")
end
end;
};
end
def test_lambda_it_no_memory_leak
# [Bug #21004]
assert_no_memory_leak(%w(-rripper), "", <<~RUBY, rss: true)
1_000_000.times do
assert_no_memory_leak(%w(-rripper), "", "#{<<-"{#"}\n#{<<-'};'}", rss: true, samples: 2..100)
{#
1000.times do
Ripper.parse("-> do it end")
end
RUBY
};
end
def test_sexp_no_memory_leak
assert_no_memory_leak(%w(-rripper), "", "#{<<~'end;'}", rss: true)
1_000_000.times do
assert_no_memory_leak(%w(-rripper), "", "#{<<-"{#"}\n#{<<-'};'}", rss: true, samples: 2..100)
{#
1000.times do
Ripper.sexp("")
end
end;
};
end
class TestInput < self
+2 -3
View File
@@ -2058,11 +2058,10 @@ class TestArray < Test::Unit::TestCase
def test_short_heap_array_sort_bang_memory_leak
bug11332 = '[ruby-dev:49166] [Bug #11332]'
assert_no_memory_leak([], <<-PREP, <<-TEST, bug11332, limit: 1.3, timeout: 60)
assert_no_memory_leak([], <<-PREP, <<-TEST, bug11332, limit: 1.3, timeout: 60, samples: 2..100)
def t; ary = [*1..5]; ary.pop(2); ary.sort!; end
1.times {t}
PREP
500000.times {t}
5_000.times {t}
TEST
end
+2 -3
View File
@@ -346,14 +346,13 @@ class TestAst < Test::Unit::TestCase
def test_invalid_yield_no_memory_leak
# [Bug #21383]
assert_no_memory_leak([], "#{<<-"begin;"}", "#{<<-'end;'}", rss: true)
assert_no_memory_leak([], "#{<<-"begin;"}", "#{<<-'end;'}", rss: true, samples: 2..100)
code = proc do
eval("class C; yield; end")
rescue SyntaxError
end
1_000.times(&code)
begin;
100_000.times(&code)
200.times(&code)
end;
end
+1 -6
View File
@@ -928,12 +928,7 @@ class TestClass < Test::Unit::TestCase
end
def test_classext_memory_leak
assert_no_memory_leak([], <<-PREP, <<-CODE, rss: true)
code = proc { Class.new }
1_000.times(&code)
PREP
3_000_000.times(&code)
CODE
assert_no_memory_leak([], "", "30_000.times {Class.new}", rss: true, samples: 2..100)
end
def test_instance_freeze_dont_freeze_the_class_bug_19164
+2 -2
View File
@@ -614,9 +614,9 @@ class TestEval < Test::Unit::TestCase
end
def test_syntax_error_no_memory_leak
assert_no_memory_leak([], "#{<<~'begin;'}", "#{<<~'end;'}", rss: true)
assert_no_memory_leak([], "#{<<~'begin;'}", "#{<<~'end;'}", rss: true, samples: 5)
begin;
100_000.times do
20_000.times do
eval("/[/=~s")
rescue SyntaxError
else
+11 -15
View File
@@ -179,9 +179,9 @@ class TestHash < Test::Unit::TestCase
end
def test_st_literal_memory_leak
assert_no_memory_leak([], "", "#{<<~"begin;"}\n#{<<~'end;'}", rss: true)
assert_no_memory_leak([], "", "#{<<~"begin;"}\n#{<<~'end;'}", rss: true, samples: 5)
begin;
1_000_000.times do
200_000.times do
# >8 element hashes are ST allocated rather than AR allocated
{a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9}
end
@@ -1523,10 +1523,10 @@ class TestHash < Test::Unit::TestCase
end
def test_compare_by_identy_memory_leak
assert_no_memory_leak([], "", "#{<<~"begin;"}\n#{<<~'end;'}", "[Bug #20145]", rss: true)
assert_no_memory_leak([], "", "#{<<~"begin;"}\n#{<<~'end;'}", "[Bug #20145]", rss: true, samples: 5)
begin;
h = { 1 => 2 }.compare_by_identity
1_000_000.times do
200_000.times do
h.select { false }
end
end;
@@ -1995,9 +1995,9 @@ class TestHashOnly < Test::Unit::TestCase
end
def test_st_literal_memory_leak
assert_no_memory_leak([], "", "#{<<~"begin;"}\n#{<<~'end;'}", rss: true)
assert_no_memory_leak([], "", "#{<<~"begin;"}\n#{<<~'end;'}", rss: true, samples: 5)
begin;
1_000_000.times do
200_000.times do
# >8 element hashes are ST allocated rather than AR allocated
{a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9}
end
@@ -2096,17 +2096,14 @@ class TestHashOnly < Test::Unit::TestCase
end
def test_rehash_memory_leak
assert_no_memory_leak([], <<~PREP, <<~CODE, rss: true)
assert_no_memory_leak([], <<~PREP, <<~CODE, rss: true, samples: 2..100)
ar_hash = 1.times.map { |i| [i, i] }.to_h
st_hash = 10.times.map { |i| [i, i] }.to_h
code = proc do
PREP
10_000.times do
ar_hash.rehash
st_hash.rehash
end
1_000.times(&code)
PREP
1_000_000.times(&code)
CODE
end
@@ -2172,11 +2169,10 @@ class TestHashOnly < Test::Unit::TestCase
end
def test_replace_memory_leak
assert_no_memory_leak([], "#{<<-"begin;"}", "#{<<-'end;'}", rss: true)
assert_no_memory_leak([], "#{<<-"begin;"}", "#{<<-'end;'}", rss: true, samples: 2..100)
h = ("aa".."zz").each_with_index.to_h
10_000.times {h.dup}
begin;
500_000.times {h.dup.replace(h)}
5_000.times {h.dup.replace(h)}
end;
end
+4 -5
View File
@@ -321,7 +321,7 @@ class TestISeq < Test::Unit::TestCase
def test_invalid_source_no_memory_leak
# [Bug #21394]
assert_no_memory_leak(["-rtempfile"], "#{<<-"begin;"}", "#{<<-'end;'}", rss: true)
assert_no_memory_leak(["-rtempfile"], "#{<<-"begin;"}", "#{<<-'end;'}", rss: true, samples: 2..100)
code = proc do |t|
RubyVM::InstructionSequence.new(nil)
rescue TypeError
@@ -329,9 +329,8 @@ class TestISeq < Test::Unit::TestCase
raise "TypeError was not raised during RubyVM::InstructionSequence.new"
end
10.times(&code)
begin;
1_000_000.times(&code)
10_000.times(&code)
end;
# [Bug #21394]
@@ -985,10 +984,10 @@ class TestISeq < Test::Unit::TestCase
end
def test_loading_kwargs_memory_leak
assert_no_memory_leak([], "#{<<~"begin;"}", "#{<<~'end;'}", rss: true)
assert_no_memory_leak([], "#{<<~"begin;"}", "#{<<~'end;'}", rss: true, samples: 5)
a = RubyVM::InstructionSequence.compile("foo(bar: :baz)").to_binary
begin;
1_000_000.times do
200_000.times do
RubyVM::InstructionSequence.load_from_binary(a)
end
end;
+2 -2
View File
@@ -1812,11 +1812,11 @@ class TestMethod < Test::Unit::TestCase
end
def test_kwarg_eval_memory_leak
assert_no_memory_leak([], "", <<~RUBY, rss: true, limit: 1.2)
assert_no_memory_leak([], "", <<~RUBY, rss: true, limit: 1.2, samples: 5)
obj = Object.new
def obj.test(**kwargs) = nil
100_000.times do
20_000.times do
eval("obj.test(foo: 123)")
end
RUBY
+6 -15
View File
@@ -3429,23 +3429,20 @@ class TestModule < Test::Unit::TestCase
def test_iclass_memory_leak
# [Bug #19550]
assert_no_memory_leak([], <<~PREP, <<~CODE, rss: true)
code = proc do
assert_no_memory_leak([], "", <<~CODE, rss: true, samples: 2..30)
100_000.times do
mod = Module.new
Class.new do
include mod
end
end
1_000.times(&code)
PREP
3_000_000.times(&code)
CODE
end
def test_complemented_method_entry_memory_leak
# [Bug #19894] [Bug #19896]
assert_no_memory_leak([], <<~PREP, <<~CODE, rss: true)
code = proc do
assert_no_memory_leak([], "", <<~CODE, rss: true, samples: 2..30)
10_000.times do
$c = Class.new do
def foo; end
end
@@ -3465,21 +3462,15 @@ class TestModule < Test::Unit::TestCase
end
end.new
end
1_000.times(&code)
PREP
300_000.times(&code)
CODE
end
def test_module_clone_memory_leak
# [Bug #19901]
assert_no_memory_leak([], <<~PREP, <<~CODE, rss: true)
code = proc do
assert_no_memory_leak([], "", <<~CODE, rss: true, samples: 2..100)
10_000.times do
Module.new.clone
end
1_000.times(&code)
PREP
1_000_000.times(&code)
CODE
end
+13 -16
View File
@@ -1009,39 +1009,36 @@ class TestRegexp < Test::Unit::TestCase
# partially parsed branch (parse_subexp freed the alternation list but not
# the node parse_branch had built so far). Regexp#to_s reaches this path
# for every /(?:a|b)c(d)/-shaped regexp.
assert_no_memory_leak([], "#{<<~"begin;"}", "#{<<~"end;"}", "[Bug #22384]", rss: true)
assert_no_memory_leak([], "#{<<~"begin;"}", "#{<<~"end;"}", "[Bug #22384]", rss: true, samples: 2..100)
code = proc do
Regexp.new("a|b(c") rescue nil
/(?:a|b)c(d)/.to_s
end
1_000.times(&code)
begin;
300_000.times(&code)
3_000.times(&code)
end;
end
def test_regsub_no_memory_leak
assert_no_memory_leak([], "#{<<~"begin;"}", "#{<<~"end;"}", rss: true)
assert_no_memory_leak([], "#{<<~"begin;"}", "#{<<~"end;"}", rss: true, samples: 2..100)
code = proc do
"aaaaaaaaaaa".gsub(/a/, "")
end
1_000.times(&code)
begin;
100_000.times(&code)
1_000.times(&code)
end;
end
def test_regsub_no_memory_leak_many_captures
assert_no_memory_leak([], "#{<<~"begin;"}", "#{<<~"end;"}", rss: true)
assert_no_memory_leak([], "#{<<~"begin;"}", "#{<<~"end;"}", rss: true, samples: 2..100)
code = proc do
"aaaaaaaaaaa".gsub(/(a)(b)?(c)?(d)?(e)?(f)?(g)?(h)?/, "")
end
1_000.times(&code)
begin;
100_000.times(&code)
1_000.times(&code)
end;
end
@@ -2107,10 +2104,10 @@ class TestRegexp < Test::Unit::TestCase
end
def test_s_timeout_memory_leak
assert_no_memory_leak([], "#{<<~"begin;"}", "#{<<~"end;"}", "[Bug #20228]", rss: true)
Regexp.timeout = 0.001
regex = /^(a*)*$/
str = "a" * 1000000 + "x"
assert_no_memory_leak([], "#{<<~"begin;"}", "#{<<~'end;'}", "[Bug #20228]", rss: true, samples: 100..200)
Regexp.timeout = 0.000001
regex = Regexp.new("^#{"(a*)" * 10_000}x$")
str = "a" * 1_000_000 + "x"
code = proc do
regex =~ str
@@ -2119,7 +2116,7 @@ class TestRegexp < Test::Unit::TestCase
10.times(&code)
begin;
1_000.times(&code)
100.times(&code)
end;
end
@@ -2196,7 +2193,7 @@ class TestRegexp < Test::Unit::TestCase
end
def test_timeout_memory_leak
assert_no_memory_leak([], "#{<<~"begin;"}", "#{<<~'end;'}", "[Bug #20650]", timeout: 100, rss: true)
assert_no_memory_leak([], "#{<<~"begin;"}", "#{<<~'end;'}", "[Bug #20650]", rss: true, samples: 100..200)
regex = Regexp.new("^#{"(a*)" * 10_000}x$", timeout: 0.000001)
str = "a" * 1_000_000 + "x"
@@ -2207,7 +2204,7 @@ class TestRegexp < Test::Unit::TestCase
10.times(&code)
begin;
1_000.times(&code)
100.times(&code)
end;
end
+1 -6
View File
@@ -652,12 +652,7 @@ class TestSetTraceFunc < Test::Unit::TestCase
# Bug #18264
def test_tracepoint_memory_leak
assert_no_memory_leak([], <<-PREP, <<-CODE, rss: true)
code = proc { TracePoint.new(:line) { } }
1_000.times(&code)
PREP
1_000_000.times(&code)
CODE
assert_no_memory_leak([], "", "10_000.times {TracePoint.new(:line) { }}", rss: true, samples: 2..100)
end
def test_tracepoint_bmethod_memory_leak
+4 -6
View File
@@ -570,21 +570,19 @@ class TestShapes < Test::Unit::TestCase
end
def test_evacuate_generic_ivar_memory_leak
assert_no_memory_leak([], "#{<<~'begin;'}", "#{<<~'end;'}", rss: true)
assert_no_memory_leak([], "#{<<~'begin;'}", "#{<<~'end;'}", rss: true, samples: 5)
o = []
o.instance_variable_set(:@a, 1)
RubyVM::Shape.exhaust_shapes
ary = 1_000_000.times.map { [] }
begin;
ary = Array.new(200_000) { [] }
ary.each do |o|
o.instance_variable_set(:@a, 1)
o.instance_variable_set(:@b, 1)
end
ary.clear
ary = nil
GC.start
end;
end
@@ -1180,13 +1178,13 @@ class TestShapes < Test::Unit::TestCase
end
def test_duplicating_complex_objects_memory_leak
assert_no_memory_leak([], "#{<<~'begin;'}", "#{<<~'end;'}", "[Bug #20162]", rss: true)
assert_no_memory_leak([], "#{<<~'begin;'}", "#{<<~'end;'}", "[Bug #20162]", rss: true, samples: 5)
RubyVM::Shape.exhaust_shapes
o = Object.new
o.instance_variable_set(:@a, 0)
begin;
1_000_000.times do
200_000.times do
o.dup
end
end;
+26 -37
View File
@@ -104,24 +104,18 @@ class TestString < Test::Unit::TestCase
def test_initialize_memory_leak
return unless @cls == String
assert_no_memory_leak([], <<-PREP, <<-CODE, rss: true)
code = proc {('x'*100_000).__send__(:initialize, '')}
1_000.times(&code)
PREP
100_000.times(&code)
CODE
assert_no_memory_leak([], '', <<-CODE, rss: true, samples: 2..100)
1_000.times {('x'*100_000).__send__(:initialize, '')}
CODE
end
# Bug #18154
def test_initialize_nofree_memory_leak
return unless @cls == String
assert_no_memory_leak([], <<-PREP, <<-CODE, rss: true)
code = proc {0.to_s.__send__(:initialize, capacity: 100_000)}
1_000.times(&code)
PREP
100_000.times(&code)
CODE
assert_no_memory_leak([], '', <<-CODE, rss: true, samples: 2..100)
1_000.times {0.to_s.__send__(:initialize, capacity: 100_000)}
CODE
end
def test_AREF # '[]'
@@ -765,12 +759,14 @@ CODE
assert_raise(ArgumentError) {S("mypassword".encode(enc)).crypt(S("aa"))}
end
@cls == String and
assert_no_memory_leak([], "s = ''; salt_proc = proc{#{(crypt_supports_des_crypt? ? '..' : good_salt).inspect}}", "#{<<~"begin;"}\n#{<<~'end;'}")
begin;
1000.times { s.crypt(-salt_proc.call).clear }
end;
if @cls == String
assert_no_memory_leak([], "#{<<~"begin;"}", "#{<<~'end;'}", samples: 2..100)
s = ''
salt = -""#{(crypt_supports_des_crypt? ? '..' : good_salt).dump}
begin;
10.times { s.crypt(salt).clear }
end;
end
end
def test_delete
@@ -2489,18 +2485,14 @@ CODE
end
def test_start_with_timeout_memory_leak
assert_no_memory_leak([], "#{<<~"begin;"}", "#{<<~'end;'}", "[Bug #20653]", rss: true)
assert_no_memory_leak([], "#{<<~"begin;"}", "#{<<~'end;'}", "[Bug #20653]", rss: true, samples: 2..100)
regex = Regexp.new("^#{"(a*)" * 10_000}x$", timeout: 0.000001)
str = "a" * 1_000_000 + "x"
code = proc do
begin;
10.times do
str.start_with?(regex)
rescue
end
10.times(&code)
begin;
1_000.times(&code)
end;
end
@@ -4520,12 +4512,11 @@ CODE
def fallback.[](_str) = raise MyError
RUBY
}.each do |type, code|
assert_no_memory_leak([], '', <<~RUBY, "fallback type is #{type}", rss: true)
assert_no_memory_leak([], <<~PREPARE, <<~RUBY, "fallback type is #{type}", rss: true, samples: 2..100)
class MyError < StandardError; end
#{code}
100_000.times do |i|
PREPARE
1000.times do |i|
"\\ufffd".encode(Encoding::US_ASCII, fallback:)
rescue MyError
end
@@ -4550,12 +4541,11 @@ CODE
def fallback.[](_str) = "\\uffee"
RUBY
}.each do |type, code|
assert_no_memory_leak([], '', <<~RUBY, "fallback type is #{type}", rss: true)
assert_no_memory_leak([], <<~PREPARE, <<~RUBY, "fallback type is #{type}", rss: true, samples: 2..100)
class MyError < StandardError; end
#{code}
100_000.times do |i|
PREPARE
1000.times do |i|
"\\ufffd".encode(Encoding::US_ASCII, fallback:)
rescue ArgumentError
end
@@ -4580,12 +4570,11 @@ CODE
def fallback.[](_str) = Object.new
RUBY
}.each do |type, code|
assert_no_memory_leak([], '', <<~RUBY, "fallback type is #{type}", rss: true)
assert_no_memory_leak([], <<~PREPARE, <<~RUBY, "fallback type is #{type}", rss: true, samples: 2..100)
class MyError < StandardError; end
#{code}
100_000.times do |i|
PREPARE
1000.times do |i|
"\\ufffd".encode(Encoding::US_ASCII, fallback:)
rescue TypeError
end
+2 -4
View File
@@ -548,15 +548,13 @@ module TestStruct
omit 'skip on riscv64-linux CI machine. See https://github.com/ruby/ruby/pull/13422' if ENV['RUBY_DEBUG'] == 'ci' && /riscv64-linux/ =~ RUBY_DESCRIPTION
# [Bug #20311]
assert_no_memory_leak([], <<~PREP, <<~CODE, rss: true, limit: 2.2)
assert_no_memory_leak([], <<~PREP, <<~CODE, rss: true, limit: 2.2, samples: 2..50)
code = proc do
Struct.new("A")
Struct.send(:remove_const, :A)
end
10_000.times(&code)
PREP
50_000.times(&code)
1_000.times(&code)
CODE
end
+5 -9
View File
@@ -1533,17 +1533,14 @@ eom
end
def test_invalid_symbol_in_hash_memory_leak
assert_no_memory_leak([], "#{<<-'begin;'}", "#{<<-'end;'}", rss: true)
assert_no_memory_leak([], "#{<<-'begin;'}", "#{<<-'end;'}", rss: true, samples: 2..1_000)
str = '{"\xC3": 1}'.force_encoding("UTF-8")
code = proc do
begin;
1_000.times do
eval(str)
raise "unreachable"
rescue SyntaxError
end
1_000.times(&code)
begin;
1_000_000.times(&code)
end;
end
@@ -2471,16 +2468,15 @@ eom
end
def test_argument_forwarding_with_super_memory_leak
assert_no_memory_leak([], "#{<<-'begin;'}", "#{<<-'end;'}", rss: true)
assert_no_memory_leak([], "#{<<-'begin;'}", "#{<<-'end;'}", rss: true, samples: 2..100)
code = proc do
eval("def foo(...) super(...) {}; end")
raise "unreachable"
rescue SyntaxError
end
1_000.times(&code)
begin;
100_000.times(&code)
1_000.times(&code)
end;
end
+2 -2
View File
@@ -204,9 +204,9 @@ class TestWeakMap < Test::Unit::TestCase
end
def test_no_memory_leak
assert_no_memory_leak([], '', "#{<<~"begin;"}\n#{<<~'end;'}", "[Bug #19398]", rss: true, limit: 1.5, timeout: 60)
assert_no_memory_leak([], '', "#{<<~"begin;"}\n#{<<~'end;'}", "[Bug #19398]", rss: true, limit: 1.5, timeout: 60, samples: 5)
begin;
1_000_000.times do
200_000.times do
ObjectSpace::WeakMap.new
end
end;
+2 -3
View File
@@ -522,12 +522,11 @@ class TestSocketAddrinfo < Test::Unit::TestCase
def test_marshal_memory_leak
bug11051 = '[ruby-dev:48923] [Bug #11051]'
assert_no_memory_leak(%w[-rsocket], <<-PREP, <<-CODE, bug11051, rss: true)
assert_no_memory_leak(%w[-rsocket], <<-PREP, <<-CODE, bug11051, rss: true, samples: 2..20)
d = Marshal.dump(Addrinfo.tcp("127.0.0.1", 80))
1000.times {Marshal.load(d)}
PREP
GC.start
20_000.times {Marshal.load(d)}
1_000.times {Marshal.load(d)}
CODE
end