Fix memory leak in rb_reg_search_set_match

https://github.com/ruby/ruby/pull/12801 changed regexp matches to reuse
the backref, which causes memory to leak if the original registers of the
match is not freed.

For example, the following script leaks memory:

    10.times do
      1_000_000.times do
        "aaaaaaaaaaa".gsub(/a/, "")
      end

      puts `ps -o rss= -p #{$$}`
    end

Before:

    774256
    1535152
    2297360
    3059280
    3821296
    4583552
    5160304
    5091456
    5114256
    4980192

After:

    12480
    11440
    11696
    11632
    11632
    11760
    11824
    11824
    11824
    11888
This commit is contained in:
Peter Zhu 2025-03-11 15:05:05 -04:00
parent 1b2cc9c2b8
commit 1cdec3240b
Notes: git 2025-03-12 01:55:22 +00:00
2 changed files with 15 additions and 0 deletions

3
re.c
View file

@ -1829,6 +1829,9 @@ rb_reg_search_set_match(VALUE re, VALUE str, long pos, int reverse, int set_back
if (NIL_P(match)) {
match = match_alloc(rb_cMatch);
}
else {
onig_region_free(&RMATCH_EXT(match)->regs, false);
}
rb_matchext_t *rm = RMATCH_EXT(match);
rm->regs = regs;