Domanda

Ciao,

Abbiamo recentemente aggiornato un'applicazione a Rails 3.0.4 (3.0.5 su Online Devel Server). La maggior parte delle modifiche da 2.3.10 a 3.0.4 erano dovute a plugin e gemme obsoleti o obsoleti e erano risolvibili con relativa facilità. Ma una cosa mi fa impazzire:

Ogni singola richiesta Web, in modalità di sviluppo, fa sì che il processo del server allocasse circa 50-60 MB più memoria di prima. Questo ricordo è non liberato dopo la richiesta, almeno non tutto. Dopo 10-20 richieste, ogni istanza di Ruby consumava 500 MB di RAM, mentre i nostri precedenti casi di Rails 2.3.10 erano raramente al di sopra di 200 MB.

Ciò rende impossibile eseguire i nostri test 1300, perché i 4 GB di RAM della macchina dello sviluppo sono riempiti prima della fine dei test. Succede solo in modalità di sviluppo con cache_classes = false. Se cambio cache_class su true, le istanze delle rotaie consumano circa 200 MB di memoria e poi rimarranno lì. Tuttavia, durante i test, anche con cache_classes = true, l'utilizzo della memoria crescerà.

Ho interrogato ObjectSpace e ho scoperto che con ogni richiesta, circa 3500 nuovi proc, fino a 50'000 nuove stringhe e 3000 nuovi hash e array vengono creati e non liberati. Queste stringhe (quando scaricate) contenevano il mio intero codice sorgente, inclusi plugin e gemme, documentazione, commenti sul codice sorgente e nomi dei percorsi. (Perché?)

Per trovare la causa per questo, ecco cosa ho provato: (Dopo ogni cambiamento, ho martellato le app ab -n 50.)

  1. Ho creato un Applicazione Fresh Rails 3 con una singola risorsa e controller e sqlite3 dB. L'utilizzo della memoria è iniziato a 60 MB e è rimasto al di sotto di 80 MB.
  2. Ho cambiato 'sqlite3' a 'pg' e ho puntato l'app New Rails 3 al mio DB Postgres esistente. L'utilizzo della memoria è iniziato a 110 MB e non è cresciuto oltre 130 MB. (Domanda laterale: perché la gemma di Postgres usa così molta più memoria della gemma SQLite3?)
  3. Ho copiato il mio Gemfile e gemfile.lock Dall'app rotto Rails3 all'app Bare Bones e ha funzionato Installazione del fascio. Nessun cambiamento, la memoria è rimasta a circa 115 MB, indipendentemente da quante richieste sono state fatte.
  4. Ho creato un vuoto "def foocontroller; def foo; render: text => 'foo' end; end" nell'app rotto Rails3. L'utilizzo della memoria è cresciuto più lentamente, ma non ha mai smesso di crescere dopo le richieste.
  5. Ho eliminato ogni percorso ad eccezione della rotta Foocontroller. Nessun cambiamento.
  6. Ho disabilitato tutte le gemme tranne le seguenti: pg, rails, aasm, will_paginate, geokit-rails3, koala, omniauth, paperclip. Nessun cambiamento.
  7. Ho disabilitato ogni prima_filter e dopo_filter in ApplicationController e ogni non essenziale include In Environment.rb. Ho anche sincronizzato Boot.rb, Environment.rb e Application.rb con la mia app Bare-Bones Rails 3, ad eccezione di cinque osservatori relativamente semplici, file di caricamento automatico in /lib e filtro_parameters. Nessun cambiamento. Ogni nuova richiesta consumava ancora un ulteriore 10-50 MB di RAM.

Se hai un'idea di cosa non va storto qui e dove potrebbe essere la perdita di memoria, apprezzerei davvero qualsiasi aiuto. Sto correndo Rails 3.0.4 su OS X Snow Leopard, Rails 3.0.5 su Debian Lenny e

Grazie!

Avvicinandosi:

Ho rimosso ogni plug -in, ogni gemma, ogni estensione e tutto ciò che non ho scritto personalmente, in modo che la mia applicazione sia sostanzialmente nuda. Soprattutto, ho rimosso questi plugin: acts_as_list, acts_as_tree, asset_packager, forgot_password, fudge_form, fudge_scaffold, paperclippolymorph, query_trace, rails_upgrade, repeated_auto_complete-0.1.0, role_requirement, to_select, validates_url, and ym4r_gm.

Ora la mia applicazione: solo il foocontroller sopra funziona ancora! - Avvia 65 MB e non va mai oltre i 75 MB di RAM, anche dopo averlo martellato con ab -n 1000 -c1 (1000 richieste HTTP a /foo usando ApacheBench). Sfortunatamente, senza i plugin, questo è anche l'unico URI che funziona affatto.

Dopo un po 'di scavo, sembra che una combinazione tra l'autenticazione riposante e funge da plug -in AMAST (State Machine (AASM) provoca la perdita di memoria. Guarda anche https://github.com/satish/restful-authentication/issues#issue/11. Non sono ancora sicuro del perché, e solo "includere aasm" nel mio progetto nudo non causa la crescita dell'utilizzo di RAM da solo.

Indagherò ulteriormente.

Colpevole trovato

È Aasm. In Rails 3 sembra perdere istanze dell'oggetto Aasm :: XXX. vedere

Secondo colpevole trovato

C'è stata un'altra perdita di memoria in RSPEC. Ciò ha reso i miei test quasi insopportabilmente lenti, anche dopo aver rimosso Aasm, perché due compiti RSPEC in esecuzione parallela (usando https://github.com/grosser/parallel_tests) ha preso quasi 3 GB di memoria alla fine. Vedere https://github.com/rspec/rspec-core/issues/#issue/321.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top