From: Eric Wong Date: 2018-05-11T03:36:41+00:00 Subject: [ruby-core:86983] Re: [Ruby trunk Bug#14745] High memory usage when using String#replace with IO.copy_stream janko.marohnic@gmail.com wrote: > the memory usage has now doubled to 100MB at the end of the > program, indicating that some string bytes weren't > successfully deallocated. So, it seems that String#replace has > different behaviour compared to String#clear + String#<<. Yes, this is an unfortunate side effect because of copy-on-write semantics of String#replace. If the arg (other_str) for String#replace is non-frozen, a new frozen string is created with using the existing malloc-ed pointer. Both the receiver string and other_str point to that new, shared string. > I was *only* able to reproduce this with `IO.copy_stream` I suspect part of this is because outbuf becomes a long-lived object with IO.copy_stream (not sure), and the hidden frozen string becomes long-lived, as well. So yeah; a combination of well-intentioned optimizations hurt when combined together. The other part could be anything using IO#write could create massive amounts of garbage before 2.5: https://bugs.ruby-lang.org/issues/13085 And your copy_stream use hits the IO#write case. Unfortunately, the "fix" for [Bug #13085] won't work effectively with shared strings, because we can't free+recycle the a string which wasn't created internally by the VM. Unsubscribe: