summaryrefslogtreecommitdiff
path: root/test/ruby
diff options
context:
space:
mode:
authornagachika <nagachika@ruby-lang.org>2024-07-07 14:42:08 +0900
committernagachika <nagachika@ruby-lang.org>2024-07-07 16:46:02 +0900
commitc97a632363a170879b9755c5a123e92533908039 (patch)
tree4d61f6e70b36e237afb616b62e2ad716fc12dae8 /test/ruby
parentbd5df1693c89d389471d145fc19b487c708912b1 (diff)
merge revision(s) 82b57d7bfeefd717c10f7a5a3484aca6b3e708a3: [Backport #20162]
Fix memory leak when duplicating too complex object [Bug #20162] Creating a ST table then calling st_replace leaks memory because the st_replace overwrites the ST table without freeing any of the existing memory. This commit changes it to use st_copy instead. For example: RubyVM::Shape.exhaust_shapes o = Object.new o.instance_variable_set(:@a, 0) 10.times do 100_000.times { o.dup } puts `ps -o rss= -p #{$$}` end Before: 23264 33600 42672 52160 61600 71728 81056 90528 100560 109840 After: 14752 14816 15584 15584 15664 15664 15664 15664 15664 15664
Diffstat (limited to 'test/ruby')
-rw-r--r--test/ruby/test_shapes.rb13
1 files changed, 13 insertions, 0 deletions
diff --git a/test/ruby/test_shapes.rb b/test/ruby/test_shapes.rb
index 47ade7e70b..7db4d0998d 100644
--- a/test/ruby/test_shapes.rb
+++ b/test/ruby/test_shapes.rb
@@ -351,6 +351,19 @@ class TestShapes < Test::Unit::TestCase
assert_shape_equal(RubyVM::Shape.of(obj), RubyVM::Shape.of(obj2))
end
+ def test_duplicating_too_complex_objects_memory_leak
+ assert_no_memory_leak([], "#{<<~'begin;'}", "#{<<~'end;'}", "[Bug #20162]", rss: true)
+ RubyVM::Shape.exhaust_shapes
+
+ o = Object.new
+ o.instance_variable_set(:@a, 0)
+ begin;
+ 1_000_000.times do
+ o.dup
+ end
+ end;
+ end
+
def test_freezing_and_duplicating_object
obj = Object.new.freeze
obj2 = obj.dup