Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save hackhowtofaq/df679b14e9561c0cbcf8 to your computer and use it in GitHub Desktop.
Save hackhowtofaq/df679b14e9561c0cbcf8 to your computer and use it in GitHub Desktop.

Revisions

  1. @brianhempel brianhempel revised this gist Feb 19, 2015. No changes.
  2. @brianhempel brianhempel revised this gist Feb 19, 2015. No changes.
  3. @brianhempel brianhempel created this gist Feb 19, 2015.
    80 changes: 80 additions & 0 deletions bench_rails_memory_usage.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,80 @@
    require "net/http"

    def start_server
    # Remove the X to enable the parameters for tuning.
    # These are the default values as of Ruby 2.2.0.
    @child = spawn(<<-EOC.split.join(" "))
    XRUBY_GC_HEAP_FREE_SLOTS=4096
    XRUBY_GC_HEAP_INIT_SLOTS=10000
    XRUBY_GC_HEAP_GROWTH_FACTOR=1.8
    XRUBY_GC_HEAP_GROWTH_MAX_SLOTS=0
    XRUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR=2.0
    XRUBY_GC_MALLOC_LIMIT=16777216
    XRUBY_GC_MALLOC_LIMIT_MAX=33554432
    XRUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR=1.4
    XRUBY_GC_OLDMALLOC_LIMIT=16777216
    XRUBY_GC_OLDMALLOC_LIMIT_MAX=134217728
    XRUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR=1.2
    rails server -p3009 > /dev/null
    EOC
    sleep 0.1 until alive?
    end

    def alive?
    system("curl http://localhost:3009/ &> /dev/null")
    end

    def stop_server
    Process.kill "HUP", server_pid
    Process.wait @child
    end

    def server_pid
    `cat tmp/pids/server.pid`.to_i
    end

    def memory_size_mb
    (`ps -o rss= -p #{server_pid}`.to_i * 1024).to_f / 2**20
    end

    # In /etc/hosts I have api.rails.local set to 127.0.0.1 for
    # API testing on any app. Curl freaks out and takes extra
    # seconds to do the request to these .local things, so we
    # will use Net::HTTP for moar speed.
    def do_request
    uri = URI("http://api.rails.local:3009/memory_heavy_action")
    req = Net::HTTP::Get.new(uri)
    # Remove the next line if you don't need HTTP basic authentication.
    req.basic_auth("[email protected]", "password")
    req["Content-Type"] = "application/json"

    Net::HTTP.start("localhost", uri.port) do |http|
    http.read_timeout = 60
    http.request(req)
    end
    end

    results = []

    # You can’t just measure once: memory usage has some variance.
    # We will take the mean of 7 runs.
    7.times do
    start_server

    used_mb = nil
    (1..30).map do |n|
    print "Request #{n}..."
    do_request
    used_mb = memory_size_mb
    puts "#{used_mb} MB"
    end

    final_mb = used_mb
    results << final_mb
    puts "Final Memory: #{final_mb} MB"

    stop_server
    end

    mean_final_mb = results.reduce(:+) / results.size
    puts "Mean Final Memory: #{mean_final_mb} MB"