title: Ruby 2.1.7 vs 2.2.3 garbage collection
body: <p>I'm seeing some weird potentially ruby 2.2.3 gc-related issues with generating a prefix tries from a list of words.  The suspect code is here: </p>
  
  <pre><code>def insert(word)
        return if word.nil? || word.empty?
        node = self
        counter = 0
        l = word.length
        #TODO _ why is this not being garbage collected?
        word.bytes.each do |i|
          counter += 1
          node.children[i] ||= Node.new(i.chr, node, counter == l)
          node = node.children[i]
          node.terminal = true if counter == l
        end
      end
  </code></pre>
  
  <p>It's being called from a list of strings - as such</p>
  
  <pre><code>words.each_with_index do |word, i|
      @root.insert(word)
  </code></pre>
  
  <p>When I do some memory profiling on this, I see the total mem usage in ruby 2.2.3-railsexpress <strong>as ~68MB:</strong></p>
  
  <pre><code>Measure Mode: memory
  Thread ID: 70102347546980
  Fiber ID: 70102348363420
  Total: 68688.375000
  Sort by: self_time
  
   %self      total      self      wait     child     calls  name
   20.03  13755.000 13755.000     0.000     0.000   293398   FastAutocomplete::Node#initialize
    9.05   6218.875  6218.875     0.000     0.000    86036   String#bytes
    6.26  66665.562  4298.438     0.000 62367.125    86040  *Array#each
    1.50   1028.969  1028.969     0.000     0.000   230540   Hash#keys
    0.98    677.219   676.438     0.000     0.781        1   Array#map
  </code></pre>
  
  <p>When I used 2.1.7, <strong>I only see about 22MB usage:</strong></p>
  
  <pre><code>    Measure Mode: memory
  Thread ID: 70216772377340
  Fiber ID: 70216782765400
  Total: 22009.125000
  Sort by: self_time
  
   %self      total      self      wait     child     calls  name
   62.49  13754.391 13754.391     0.000     0.000   293398   FastAutocomplete::Node#initialize
   28.25   6218.641  6218.641     0.000     0.000    86036   String#bytes
    4.67   1028.078  1028.078     0.000     0.000   230540   Hash#keys
    3.07    676.797   676.203     0.000     0.594        1   Array#map
    1.27    280.203   280.203     0.000     0.000   116093   Thread::Queue#enq
    0.07     19.297    15.516     0.000     3.781        9   JSON::Ext::Generator::GeneratorMethods::Hash#to_json
  </code></pre>
  
  <p>I've tried multiple things like tracking GC.stats throughout the creation process, but haven't noticed anything particularly telling.  I've also tried using string.each_char or string.split('').each (i.e. different iterators). </p>
  
  <p>Any ideas as to why 2.2.3 is using 3x the memory?  This is causing some of our servers to blow up.</p>