Vraag Hoe te meten hoeveel geheugen elke edelsteen bij de initialisatie nodig heeft?


Ik heb een Rails 2.3.10 app met bundler. Bij het opstarten is de geheugenvoetafdruk vrij groot (300 MB in ontwikkelmodus).

Ik zou graag willen zien hoeveel geheugen elke edelsteen bij het opstarten in beslag neemt.


12
2017-10-25 09:20


oorsprong


antwoorden:


We hadden een probleem waarbij onze Basic Rails-app, zonder verkeer of verzoeken, bij het opstarten een footprint van ~ 140 MB had.

We gebruikten de volgende aanpak om de geheugenvereisten van elk juweel dat is opgegeven in het Gemfile van onze app te traceren, zonder te proberen om een ​​bundler te patchen.

  1. gebruik makend van rails new myappname een nieuwe lege rails-app genereren
  2. Kopieer het Gemfile van het hoofdproject naar dit nieuwe railsproject
  3. rennen bundle install en dan rails server om ervoor te zorgen dat het mogelijk is om de rails-server op te starten en dat alle vereiste basisconfiguraties zijn geladen
  4. Open de Gemfile en voeg met uitzondering van de specificatie voor de rails-edelsteen toe require: false aan het einde van elke regel. Zorg ervoor dat alle andere edelstenen die zijn opgegeven met één naam maar verplicht zijn met: require => 'othergemname', de oudere robijn-hash-notatie gebruiken, zodat de onderstaande patroonovereenkomst deze kan bevatten.
  5. Rennen bundle install om het Gemfile.lock opnieuw te genereren
  6. Maak het volgende script dat handmatig elke edelsteen zal gebruiken die is gespecificeerd in het Gemfile en log het systeemgeheugen dat wordt verbruikt door het rails-proces voor en na.

    # require_and_profile.rb
    def require_and_profile(gemname = nil)
      unless gemname
        puts "%-20s: %10s | %10s" % ['gem','increment','total']
        return
      end
      # This is how to get memory of calling process in OS X, check host OS for variants
      memory_usage = `ps -o rss= -p #{Process.pid}`.to_i / 1024.0
      require gemname
      puts "%-20s: %10.2f | %10.2f" % [ gemname, (`ps -o rss= -p #{Process.pid}`.to_i / 1024.0 - memory_usage), (`ps -o rss= -p #{Process.pid}`.to_i / 1024.0)]
    end
    
    pattern = /^[^#]*gem[ ]*['"]([^,'"]*)['"][ ,~>0-9\.'"]*(:require[ => ]*['"]([^'"]*)['"][, ])?/
    
    require_and_profile
    File.open('Gemfile').each do |line|
      if line.match(pattern)
      if line.match(pattern)[3]
        require_and_profile line.match(pattern)[3]
      else
          require_and_profile line.match(pattern)[1]
        end
      end
    end
    
  7. Rennen rails c

  8. load 'require_and_profile.rb'
  9. De uitvoer toont hoeveel (in MB) elke edelsteen bijdraagt ​​aan de voetafdruk van de basisapp (toename) en wat de totale voetafdruk is na opname van de edelsteen (totaal).

Dit hielp ons bijvoorbeeld te identificeren dat we activasynchronisatie nodig hadden in onze boot toen we het alleen nodig hadden in de: activagroep. We vinden wel dat bij verschillende boot-ups de geheugenvoetafdruk van elk juweel niet precies hetzelfde is, maar als je het een paar keer gebruikt, zie je de patronen waarvan die geheugenhongerige edelstenen zijn.


19
2017-09-11 02:45



Er is een eenvoudigere manier om dit nu met de ontspoorde edelsteen te doen:

voeg toe aan je gemfile:

gem 'derailed', group: :development

vervolgens op de opdrachtregel vanuit de root van uw app:

bundle exec derailed bundle:mem

Dit drukt uit hoeveel geheugen elk juweel neemt als het wordt meegeleverd.


10
2018-04-26 21:33



Ik zou het als volgt doen:

  • Vind de plaats binnen bundler waar alle edelstenen nodig zijn.
  • nadat elke edelsteen is vereist, verkrijgt u het huidige aantal objecten (c = 0; ObjectSpace.each_object { c += 1 })

Op deze manier zie je welk juweel de meeste objecten veroorzaakt die worden geïnstantieerd en daarom indirect het meeste geheugengebruik veroorzaakt.

Twee kanttekeningen echter:

  • geheugengebruik is niet echt lineair met het aantal objecten, maar je moet een schatting krijgen die goed genoeg is over welke edelstenen de ergste overtreders zijn
  • zoals al opgemerkt: edelstenen laden mogelijk niet al hun code wanneer nodig, dus een edelsteen kan later meer geheugengebruik veroorzaken wanneer er meer code wordt geladen ...

0
2017-10-25 10:47