diff options
| author | NARUSE, Yui <nurse@users.noreply.github.com> | 2024-02-01 16:19:48 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-02-01 07:19:48 +0000 |
| commit | 3fb51b93d25b0566b71249b1c7ccddf0dab91429 (patch) | |
| tree | 403357f6ba15359b316a8b9092742037584f8b04 /object.c | |
| parent | 7231fc5baa0a44ef6264c795071c5fbec8d1102d (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.c | 3 |
1 files changed, 1 insertions, 2 deletions
@@ -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; |
