# File lib/mini_profiler/gc_profiler.rb, line 92
  def profile_gc(app, env)

    # for memsize_of
    require 'objspace'

    # clean up before
    GC.start
    stat          = GC.stat
    prev_gc_state = GC.disable
    stat_before   = object_space_stats
    b             = app.call(env)[2]
    b.close if b.respond_to? :close
    stat_after = object_space_stats
    # so we don't blow out on memory
    prev_gc_state ? GC.disable : GC.enable

    diff                          = diff_object_stats(stat_before[:stats],stat_after[:stats])
    string_analysis               = analyze_strings(stat_before[:ids], stat_after[:ids])
    new_objects, memory_allocated = analyze_growth(stat_before[:ids], stat_after[:ids])
    objects_before, memory_before = analyze_initial_state(stat_before[:ids])

    body = []

    body << "
Overview
--------
Initial state: object count: #{objects_before}
Memory allocated outside heap (bytes): #{memory_before}

GC Stats:
--------
#{stat.map{|k,v| "#{k} : #{v}" }.sort!.join("\n")}

New bytes allocated outside of Ruby heaps: #{memory_allocated}
New objects: #{new_objects}
"

    body << "
ObjectSpace delta caused by request:
-----------------------------------\n"
    diff.to_a.delete_if{|_k, v| v == 0}.sort_by! { |_k, v| v }.reverse_each do |k,v|
      body << "#{k} : #{v}\n"
    end

    body << "\n
ObjectSpace stats:
-----------------\n"

    stat_after[:stats].to_a.sort_by!{ |_k, v| v }.reverse_each do |k,v|
      body << "#{k} : #{v}\n"
    end


    body << "\n
String stats:
------------\n"

    string_analysis.to_a.sort_by!{ |_k, v| -v }.take(1000).each do |string,count|
      body << "#{count} : #{string}\n"
    end

    return [200, {'Content-Type' => 'text/plain'}, body]
  ensure
    prev_gc_state ? GC.disable : GC.enable
  end