Fix string memory leaks in Ruby 1.8.6
UPDATE: This is rails-incompatible... which sucks.
Ruby 1.8.6 leaks memory in some surprising places. Even gsub and split on the String class cause some bad headaches. If you're using Haml and 1.8.6 - you are probably in a bit of trouble.
Read more: http://blog.edhickey.com/2008/12/03/memory-leak-in-ruby-186-string-class/
However, simply overwriting the offending methods fixes this memory leak at least. With a weird caveat that you may not use $ variables (eg $1) in any blocks passed to gsub.
Re-read that last sentence... "boom".gsub(/b(.)/) {|m| $1.upcase} will NO LONGER work. Unfortunately... rails uses that syntax, making this blog post probably moot
-
class ::String
-
# This below fixes a bad memory leak in ruby 1.8.6
-
# http://blog.edhickey.com/2008/12/03/memory-leak-in-ruby-186-string-class/
-
alias :non_garbage_split :split
-
alias :non_garbage_gsub :gsub
-
alias :non_garbage_gsub! :gsub!
-
-
def split(char)
-
holder = char
-
non_garbage_split(holder)
-
end
-
-
def gsub(*args, &block)
-
if args.size == 1
-
non_garbage_gsub(args[0], &block)
-
else
-
non_garbage_gsub(args[0], args[1], &block)
-
end
-
end
-
-
def gsub!(*args, &block)
-
holder = args[0]
-
args[0] = holder
-
non_garbage_gsub!(*args, &block)
-
end
-
#end memory leak fixes
-
end

Try something like:
alias mri_gsub gsub
def gsub(*args,&block)
mri_gsub(*args,&block)
end
It handles $1 et al fine. Also, you should do the same trick with sub, sub!, etc.
– MarkusQ
My bad, I failed to test it thoroughly. It works for special cases, but what is needed is a “works always.”
– Markus
P.S. After looking at the C code (and this time testing before I post) I see that File#gets & $_ have the same problem.