Project

General

Profile

Actions

Bug #15916

closed

Memory leak in Regexp literal interpolation

Added by mltsy (Joe Marty) almost 5 years ago. Updated over 4 years ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux]
[ruby-core:93071]

Description

When interpolating a string inside a Regexp literal, if the string contains a multibyte character loaded from a file (not sure if this covers all the cases, but this is what triggers it for me), Ruby leaks memory.

The code below reproduces the problem, while outputting the process memory usage as it rises (get_process_mem gem is required).

Ways to avoid the memory leak (although I don't know why) include:

  1. Using the string literal to define PATTERN directly (Not loading it from a file)
  2. Using Regexp.new instead of a literal interpolation (/#{...}/)
  3. Shortening the string to just a few characters (maybe small enough to fit inside a single RVALUE?)
require 'get_process_mem'

str = "String that doesn't fit into a single RVALUE, with a multibyte char:" + 160.chr(Encoding::UTF_8)
File.write('weirdstring.txt', str)
pattern = File.read("weirdstring.txt")

loop do
  print "Running... "

  100_000.times { /#{pattern}/i }

  puts " process mem: #{GetProcessMem.new.mb.to_i}MB"
end

Expected Result:
Constant memory usage (avoiding the leak produces constant memory usage between 10-20MB)

Actual Result:
Continual memory growth (it only takes 60 seconds or so to consume 500MB)


Related issues 2 (0 open2 closed)

Related to Ruby master - Bug #16041: eval's path argument seems to trigger GC bugClosedko1 (Koichi Sasada)Actions
Related to Ruby master - Bug #16136: String corruption in 2.6.4ClosedActions
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0