diff options
author | Peter Zhu <[email protected]> | 2024-01-03 15:59:37 -0500 |
---|---|---|
committer | Peter Zhu <[email protected]> | 2024-01-04 11:25:31 -0500 |
commit | 6c252912af4981f016a9abdb4c1689307a4f1d2f (patch) | |
tree | 29aaa7c2ba9770f9a99058bc73d2a84857287bd6 /hash.c | |
parent | 542011ff6895f77204349ddfae7dcfb476e116df (diff) |
Memory leak when duplicating identhash
[Bug #20145]
Before this commit, both copy_compare_by_id and hash_copy will create a
copy of the ST table, so the ST table created in copy_compare_by_id will
be leaked.
h = { 1 => 2 }.compare_by_identity
10.times do
1_000_000.times do
h.select { false }
end
puts `ps -o rss= -p #{$$}`
end
Before:
110736
204352
300272
395520
460704
476736
542000
604704
682624
770528
After:
15504
16048
16144
16256
16320
16320
16752
16752
16752
16752
Diffstat (limited to 'hash.c')
-rw-r--r-- | hash.c | 10 |
1 files changed, 9 insertions, 1 deletions
@@ -1558,7 +1558,15 @@ hash_copy(VALUE ret, VALUE hash) static VALUE hash_dup_with_compare_by_id(VALUE hash) { - return hash_copy(copy_compare_by_id(rb_hash_new(), hash), hash); + VALUE dup = hash_alloc_flags(rb_cHash, 0, Qnil, RHASH_ST_TABLE_P(hash)); + if (RHASH_ST_TABLE_P(hash)) { + RHASH_SET_ST_FLAG(dup); + } + else { + RHASH_UNSET_ST_FLAG(dup); + } + + return hash_copy(dup, hash); } static VALUE |