mirror of
https://github.com/ruby/ruby.git
synced 2025-09-15 16:44:01 +02:00
merge revision(s) 6c252912af
: [Backport #20145]
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 --- hash.c | 10 +++++++++- test/ruby/test_hash.rb | 10 ++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-)
This commit is contained in:
parent
f585171a6b
commit
aeffb5e21d
3 changed files with 20 additions and 2 deletions
10
hash.c
10
hash.c
|
@ -1557,7 +1557,15 @@ hash_copy(VALUE ret, VALUE hash)
|
||||||
static VALUE
|
static VALUE
|
||||||
hash_dup_with_compare_by_id(VALUE hash)
|
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
|
static VALUE
|
||||||
|
|
|
@ -1458,6 +1458,16 @@ class TestHash < Test::Unit::TestCase
|
||||||
assert_predicate(h.dup, :compare_by_identity?, bug8703)
|
assert_predicate(h.dup, :compare_by_identity?, bug8703)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_compare_by_identy_memory_leak
|
||||||
|
assert_no_memory_leak([], "", "#{<<~"begin;"}\n#{<<~'end;'}", "[Bug #20145]", rss: true)
|
||||||
|
begin;
|
||||||
|
h = { 1 => 2 }.compare_by_identity
|
||||||
|
1_000_000.times do
|
||||||
|
h.select { false }
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
|
||||||
def test_same_key
|
def test_same_key
|
||||||
bug9646 = '[ruby-dev:48047] [Bug #9646] Infinite loop at Hash#each'
|
bug9646 = '[ruby-dev:48047] [Bug #9646] Infinite loop at Hash#each'
|
||||||
h = @cls[a=[], 1]
|
h = @cls[a=[], 1]
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
|
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
|
||||||
#define RUBY_VERSION_TEENY 0
|
#define RUBY_VERSION_TEENY 0
|
||||||
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
|
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
|
||||||
#define RUBY_PATCHLEVEL 4
|
#define RUBY_PATCHLEVEL 5
|
||||||
|
|
||||||
#include "ruby/version.h"
|
#include "ruby/version.h"
|
||||||
#include "ruby/internal/abi.h"
|
#include "ruby/internal/abi.h"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue