Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Puma memory usage #1063

Closed
mperham opened this issue Aug 31, 2016 · 10 comments
Closed

Puma memory usage #1063

mperham opened this issue Aug 31, 2016 · 10 comments

Comments

@mperham
Copy link

mperham commented Aug 31, 2016

I was auditing a trivial Rails 5.0.0 app using https://github.com/schneems/derailed_benchmarks#use and noticed that Puma 3.6.0 seems to grab a lot of memory on startup - not a ton but just enough to be at the top. The main offender seems to be the large number of constants in puma/const. Could some of these constants be lazy loaded in server mode only (i.e. not when requiring 'puma')?

retained memory by gem
-----------------------------------
    129053  puma-3.6.0
     71518  sidekiq/lib
     57722  sqlite3-1.3.11
     44271  redis-3.3.1
     42040  ent/lib
     36486  pro/lib
     22384  redis-namespace-1.5.2
      9902  activesupport-5.0.0.1
      7236  statsd-ruby-1.3.0
      6433  bundler-1.12.5
      5684  connection_pool-2.2.0
      4272  ruby-2.3.0/lib
       420  railties-5.0.0.1

retained memory by file
-----------------------------------
     22080  /Users/mike/.gem/ruby/2.3.0/gems/puma-3.6.0/lib/puma/const.rb
     18541  /Users/mike/src/sidekiq/lib/sidekiq/redis_connection.rb
     17077  /Users/mike/.gem/ruby/2.3.0/gems/sqlite3-1.3.11/lib/sqlite3/errors.rb
     16735  /Users/mike/.gem/ruby/2.3.0/gems/puma-3.6.0/lib/puma.rb
     16385  /Users/mike/.gem/ruby/2.3.0/gems/puma-3.6.0/lib/puma/configuration.rb
     15678  /Users/mike/.gem/ruby/2.3.0/gems/puma-3.6.0/lib/puma/server.rb
     15294  /Users/mike/.gem/ruby/2.3.0/gems/redis-3.3.1/lib/redis/errors.rb
     13989  /Users/mike/.gem/ruby/2.3.0/gems/redis-namespace-1.5.2/lib/redis/namespace.rb
     13492  /Users/mike/.gem/ruby/2.3.0/gems/sqlite3-1.3.11/lib/sqlite3/database.rb
     12981  /Users/mike/src/sidekiq/lib/sidekiq.rb
     12808  /Users/mike/src/sidekiq/lib/sidekiq/api.rb
     12634  /Users/mike/.gem/ruby/2.3.0/gems/puma-3.6.0/lib/puma/launcher.rb

Full gist: https://gist.github.com/mperham/399f0ed0eca321aeaf9ee20cf104a849

@evanphx
Copy link
Member

evanphx commented Sep 5, 2016

Oddly those line numbers don't match up but I agree, there are some large Hashes in const that can be cleaned up. Let me see about moving where it's required as well.

@evanphx evanphx closed this as completed in 5fdf337 Sep 5, 2016
@mperham
Copy link
Author

mperham commented Sep 5, 2016

Awesome. Testing the results now. Before:

Measuring objects created by gems in groups [:default, "production"]
Total allocated: 4246065 bytes (34727 objects)
Total retained:  437421 bytes (4179 objects)

allocated memory by gem
-----------------------------------
   1348174  puma-3.6.0
    749251  sidekiq/lib
    538517  pro/lib
    397726  ent/lib
    390783  sqlite3-1.3.11
    366598  redis-3.3.1
    143032  bundler-1.12.5
    119089  redis-namespace-1.5.2
     84124  statsd-ruby-1.3.0
     52623  connection_pool-2.2.0
     25766  ruby-2.3.0/lib
     25330  activesupport-5.0.0.1
      4972  railties-5.0.0.1
        80  derailed_benchmarks-1.3.1

allocated memory by file
-----------------------------------
    376210  /Users/mike/src/sidekiq/lib/sidekiq/redis_connection.rb
    328169  /Users/mike/.gem/ruby/2.3.0/gems/puma-3.6.0/lib/puma/server.rb
    297164  /Users/mike/.gem/ruby/2.3.0/gems/puma-3.6.0/lib/puma.rb
    267768  /Users/mike/.gem/ruby/2.3.0/gems/puma-3.6.0/lib/puma/launcher.rb
    237737  /Users/mike/src/sidekiq/lib/sidekiq.rb
    220417  /Users/mike/.gem/ruby/2.3.0/gems/redis-3.3.1/lib/redis.rb
    198843  /Users/mike/.gem/ruby/2.3.0/gems/sqlite3-1.3.11/lib/sqlite3/database.rb
    190144  /Users/mike/.gem/ruby/2.3.0/gems/puma-3.6.0/lib/puma/configuration.rb
    189821  /Users/mike/src/pro/lib/sidekiq/pro/api.rb
    187532  /Users/mike/src/ent/lib/sidekiq-ent.rb
    184554  /Users/mike/src/ent/lib/sidekiq-ent/limiter.rb
    164701  /Users/mike/src/pro/lib/sidekiq/batch.rb
    149197  /Users/mike/src/pro/lib/sidekiq-pro.rb
    142872  /Users/mike/.gem/ruby/2.3.0/gems/bundler-1.12.5/lib/bundler/runtime.rb
    108896  /Users/mike/.gem/ruby/2.3.0/gems/sqlite3-1.3.11/lib/sqlite3.rb
     93205  /Users/mike/.gem/ruby/2.3.0/gems/redis-3.3.1/lib/redis/connection.rb
     90357  /Users/mike/.gem/ruby/2.3.0/gems/redis-namespace-1.5.2/lib/redis-namespace.rb
     79214  /Users/mike/.gem/ruby/2.3.0/gems/puma-3.6.0/lib/puma/reactor.rb
     77809  /Users/mike/.gem/ruby/2.3.0/gems/statsd-ruby-1.3.0/lib/statsd-ruby.rb
     61038  /Users/mike/.gem/ruby/2.3.0/gems/puma-3.6.0/lib/puma/const.rb

@mperham
Copy link
Author

mperham commented Sep 5, 2016

DAAAAAAMN, SON. Making me look bad! After:

$ bundle exec derailed bundle:objects
Measuring objects created by gems in groups [:default, "production"]
Total allocated: 2900975 bytes (23618 objects)
Total retained:  309364 bytes (2885 objects)

allocated memory by gem
-----------------------------------
    749250  sidekiq/lib
    538517  pro/lib
    397726  ent/lib
    390823  sqlite3-1.3.11
    366518  redis-3.3.1
    144092  bundler-1.12.5
    119089  redis-namespace-1.5.2
     84124  statsd-ruby-1.3.0
     52623  connection_pool-2.2.0
     25766  ruby-2.3.0/lib
     25330  activesupport-5.0.0.1
      4972  railties-5.0.0.1
      2065  puma-5fdf337790a6
        80  derailed_benchmarks-1.3.1

allocated memory by file
-----------------------------------
    376209  /Users/mike/src/sidekiq/lib/sidekiq/redis_connection.rb
    237737  /Users/mike/src/sidekiq/lib/sidekiq.rb
    220337  /Users/mike/.gem/ruby/2.3.0/gems/redis-3.3.1/lib/redis.rb
    198883  /Users/mike/.gem/ruby/2.3.0/gems/sqlite3-1.3.11/lib/sqlite3/database.rb
    189821  /Users/mike/src/pro/lib/sidekiq/pro/api.rb
    187532  /Users/mike/src/ent/lib/sidekiq-ent.rb
    184554  /Users/mike/src/ent/lib/sidekiq-ent/limiter.rb
    164701  /Users/mike/src/pro/lib/sidekiq/batch.rb
    149197  /Users/mike/src/pro/lib/sidekiq-pro.rb
    143932  /Users/mike/.gem/ruby/2.3.0/gems/bundler-1.12.5/lib/bundler/runtime.rb
    108896  /Users/mike/.gem/ruby/2.3.0/gems/sqlite3-1.3.11/lib/sqlite3.rb
     93205  /Users/mike/.gem/ruby/2.3.0/gems/redis-3.3.1/lib/redis/connection.rb
     90357  /Users/mike/.gem/ruby/2.3.0/gems/redis-namespace-1.5.2/lib/redis-namespace.rb
     77809  /Users/mike/.gem/ruby/2.3.0/gems/statsd-ruby-1.3.0/lib/statsd-ruby.rb
     49577  /Users/mike/.gem/ruby/2.3.0/gems/connection_pool-2.2.0/lib/connection_pool.rb
     42500  /Users/mike/.gem/ruby/2.3.0/gems/sqlite3-1.3.11/lib/sqlite3/statement.rb
     35237  /Users/mike/src/sidekiq/lib/sidekiq/client.rb
     33343  /Users/mike/src/sidekiq/lib/sidekiq/worker.rb
     27540  /Users/mike/.gem/ruby/2.3.0/gems/redis-namespace-1.5.2/lib/redis/namespace.rb
     25328  /Users/mike/.gem/ruby/2.3.0/gems/redis-3.3.1/lib/redis/connection/ruby.rb
     24850  /Users/mike/.gem/ruby/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/core_ext/class/attribute.rb
     23423  /Users/mike/src/pro/lib/sidekiq/pro/config.rb
     20798  /Users/mike/.rubies/ruby-2.3.0/lib/ruby/2.3.0/forwardable.rb
     18244  /Users/mike/src/sidekiq/lib/sidekiq/util.rb

@mperham
Copy link
Author

mperham commented Sep 5, 2016

Seems like I need to move my APIs to autoload to minimize the memory overhead of unused features.

@evanphx
Copy link
Member

evanphx commented Sep 5, 2016

Glad to know that will help sidekiq processes!
On Mon, Sep 5, 2016 at 12:43 PM Mike Perham notifications@github.com
wrote:

Seems like I need to move my APIs to autoload to minimize the memory
overhead of unused features.


You are receiving this because you modified the open/close state.

Reply to this email directly, view it on GitHub
#1063 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAAAB2AQscRZHid4cNdyIJ1mIXM-qRjrks5qnHDGgaJpZM4Jxx5-
.

@schneems
Copy link
Contributor

schneems commented Sep 5, 2016

For apps that need the constants loaded, moving to autoload can increase memory since it's no longer taking advantage of CoW.

@evanphx
Copy link
Member

evanphx commented Sep 5, 2016

It's only autoloaded by puma.rb. All other usages will load everything as
soon as it's clear that puma is being used (rack handler, cli, etc). This
change just prevents puma from loading everything when Bundler requires it.
On Mon, Sep 5, 2016 at 1:47 PM Richard Schneeman notifications@github.com
wrote:

For apps that need the constants loaded, moving to autoload can increase
memory since it's no longer taking advantage of CoW.


You are receiving this because you modified the open/close state.

Reply to this email directly, view it on GitHub
#1063 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAAAB22PE-gFbJQFYr-6N0zhBkxwmOUJks5qnH_5gaJpZM4Jxx5-
.

@schneems
Copy link
Contributor

schneems commented Sep 5, 2016

Great! Thanks for the patch! 🚀👏

@mecampbellsoup
Copy link

@evanphx could we get a link to the relevant pull request or commit to see what you changed? Trying to learn something today!

@frodsan
Copy link
Contributor

frodsan commented Sep 6, 2016

@mecampbellsoup 5fdf337

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants