summaryrefslogtreecommitdiff
path: root/object.c
diff options
context:
space:
mode:
authorNARUSE, Yui <nurse@users.noreply.github.com>2024-02-01 16:19:48 +0900
committerGitHub <noreply@github.com>2024-02-01 07:19:48 +0000
commit3fb51b93d25b0566b71249b1c7ccddf0dab91429 (patch)
tree403357f6ba15359b316a8b9092742037584f8b04 /object.c
parent7231fc5baa0a44ef6264c795071c5fbec8d1102d (diff)
merge revision(s) 82b57d7bfeefd717c10f7a5a3484aca6b3e708a3: [Backport… (#9795)
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 --- object.c | 3 +-- test/ruby/test_shapes.rb | 13 +++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-)
Diffstat (limited to 'object.c')
-rw-r--r--object.c3
1 files changed, 1 insertions, 2 deletions
diff --git a/object.c b/object.c
index cde1d7b1d6..cdb8341082 100644
--- a/object.c
+++ b/object.c
@@ -301,8 +301,7 @@ rb_obj_copy_ivar(VALUE dest, VALUE obj)
if (rb_shape_obj_too_complex(obj)) {
// obj is TOO_COMPLEX so we can copy its iv_hash
- st_table * table = rb_st_init_numtable_with_size(rb_st_table_size(ROBJECT_IV_HASH(obj)));
- st_replace(table, ROBJECT_IV_HASH(obj));
+ st_table *table = st_copy(ROBJECT_IV_HASH(obj));
rb_obj_convert_to_too_complex(dest, table);
return;