2015-11-11 6 views
9

Sto utilizzando Twitter, Mongo e Parallel in un ciclo per recuperare e archiviare i dati.1 GB di memoria allocata a "lib/ruby ​​/ 2.1.0/timeout.rb"

memoria utilizzo colpire 1.5GB +

Come viene GC non pulire questo?

UPDATE:Here is the script in question.

allocated memory by location 
----------------------------------- 
973409328 /Users/jordan/.rvm/rubies/ruby-2.1.5/lib/ruby/2.1.0/timeout.rb:82 
359655091 /Users/jordan/.rvm/gems/ruby-2.1.5/gems/json-1.8.3/lib/json/common.rb:155 
    34706221 /Users/jordan/.rvm/rubies/ruby-2.1.5/lib/ruby/2.1.0/openssl/buffering.rb:182 
    31767589 /Users/jordan/.rvm/rubies/ruby-2.1.5/lib/ruby/2.1.0/net/http/response.rb:368 
    22055648 /Users/jordan/.rvm/gems/ruby-2.1.5/gems/parallel-1.6.1/lib/parallel.rb:183 
    12129637 /Users/jordan/.rvm/gems/ruby-2.1.5/gems/addressable-2.3.8/lib/addressable/uri.rb:525 
    11115133 /Users/jordan/.rvm/rubies/ruby-2.1.5/lib/ruby/2.1.0/net/protocol.rb:172 
    10609088 /Users/jordan/.rvm/gems/ruby-2.1.5/gems/addressable-2.3.8/lib/addressable/idna/pure.rb:177 
    8333448 /Users/jordan/.rvm/gems/ruby-2.1.5/gems/twitter-5.15.0/lib/twitter/base.rb:152 
    6041744 /Users/jordan/.rvm/gems/ruby-2.1.5/gems/thread_safe-0.3.5/lib/thread_safe/non_concurrent_cache_backend.rb:8 
    4857232 /Users/jordan/.rvm/gems/ruby-2.1.5/gems/addressable-2.3.8/lib/addressable/uri.rb:1477 
    4583920 /Users/jordan/.rvm/rubies/ruby-2.1.5/lib/ruby/2.1.0/monitor.rb:241 
    4524872 /Users/jordan/.rvm/gems/ruby-2.1.5/gems/memoizable-0.4.2/lib/memoizable/method_builder.rb:117 
    4282752 /Users/jordan/.rvm/gems/ruby-2.1.5/gems/twitter-5.15.0/lib/twitter/base.rb:151 
    4200641 /Users/jordan/.rvm/gems/ruby-2.1.5/gems/mongo-2.1.1/lib/mongo/monitoring/command_log_subscriber.rb:104 
    3283047 /Users/jordan/.rvm/rubies/ruby-2.1.5/lib/ruby/2.1.0/net/http/response.rb:61 
    3150696 /Users/jordan/.rvm/gems/ruby-2.1.5/gems/mongo-2.1.1/lib/mongo/server/monitor.rb:125 


allocated memory by gem 
----------------------------------- 
1084770550 ruby-2.1.5/lib 
359655091 json-1.8.3 
    53016839 addressable-2.3.8 
    22069048 parallel-1.6.1 
    18422826 twitter-5.15.0 
    10829988 mongo-2.1.1 
    8908392 memoizable-0.4.2 
    6041744 thread_safe-0.3.5 
    4904294 faraday-0.9.2 
    3839455 other 
    3382080 naught-1.1.0 
    2429320 bson-3.2.6 
    1123917 rubygems 
    320962 rollbar-2.4.0 
    205097 activesupport-4.2.4 
    20005 multi_json-1.11.2 
+0

senza codice visualizzato non è possibile dire il motivo per cui le perdite. È improbabile che Ruby 2.1.5 si scarichi da solo. Se il codice è complicato da postare su SO, suggerirei alcuni strumenti di debug come ['gc_tracer'] (https://github.com/ko1/gc_tracer) scritti dallo stesso autore di VM e GC. – joanbm

+0

Btw. l'uso errato del modulo 'Timeout' può causare perdite di memoria. Viene frequentemente ignorato, l'eccezione di timeout può sorgere ovunque persino nei blocchi di sicurezza o di salvataggio, se non esplicitamente gestita. – joanbm

+0

Sì, come dovrei usarlo? –

risposta

3

gestione della memoria Ruby è elegante e ingombrante. Memorizza oggetti (denominati RVALUE s) in cosiddetti heap di dimensioni di circa 16 KB. A livello basso, RVALUE è un c -struct, contenente un unione di diverse rappresentazioni standard di oggetti ruby.

Quindi, gli heap archiviano gli oggetti RVALUE, la cui dimensione non è superiore a 40 byte. Per oggetti come String, Array, Hash ecc. Ciò significa che piccoli oggetti possono essere contenuti nell'heap, ma non appena raggiungono una soglia, verrà assegnata una memoria extra al di fuori degli heap di Ruby.

Questa memoria aggiuntiva è flessibile; sarà liberato non appena un oggetto diventerà GC. Ma gli stessi heap non vengono più rilasciati sul sistema operativo.

Detto questo, una volta che si sta caricando molti brevi stringhe in memoria rubino contemporaneamente, importo cumuli è in aumento e questa memoria non è mai restituito Torna a Ruby. Questo potrebbe sembrare strano, ma provare per favore non per memorizzare stringhe, più corto di 23 simboli. Quel folle, mi spiace per la proposta :)

che potrebbe aiutare pure: http://www.sitepoint.com/ruby-uses-memory/

+0

Grazie per i dettagli tecnici - Non l'ho mai saputo di Ruby! Tuttavia, non sono sicuro di come implementare il tuo feedback. Collegheresti ad esempi nella fonte che potrebbe essere responsabile della memorizzazione di troppe stringhe? https://gist.github.com/jfeldstein/3769902a50ebef1fb536 Non è ovvio per me come eseguire ciò che sto facendo senza memorizzare stringhe ... –

+0

Sospetto linee come quella: https: //gist.github. com/jfeldstein/3769902a50ebef1fb536 # file-twitter_enrichment-rb-L157 Questo 'map' gorges 5000 slot (heap) in una volta. Prova a giocare con esso (ad esempio usa '500' invece di' 5000',) ma, onestamente, non sono sicuro che ci sia un modo semplice per migliorare significativamente il consumo di memoria. Forse è un buon momento per provare [Elixir] (http://elixir-lang.org/) :) – mudasobwa

+1

BTW, la domanda originale _ "In che modo GC non ripulisce questo?" È più o meno la risposta sopra riportata. – mudasobwa

3

si sta caricando in un tonnellata dei dati (a seconda di quanti utenti avete) e poi dormire per 20 secondi in parallelo. Quindi, in pratica, se hai un centinaio di utenti, recuperi i dati di Twitter per 100 utenti contemporaneamente e poi dormi, lo fai di nuovo e così via. Probabilmente questa memoria sembra essere stata attribuita al processo di timeout perché questo è il responsabile di questo durante il riposo di 20 secondi.

provare a ridurre il numero di thread che si sta utilizzando da keys.length solo a pochi (giocare con il numero)

+0

L'ho eseguito in un singolo thread - È ancora gonfio. Penso di mantenere il riferimento ai risultati di ogni query di mongo, o di una chiamata HTTP ... ma posso 't determinare dove –

+2

Il problema potrebbe diventare più chiaro se lo script refactoring è completamente orientato agli oggetti. In passato, sono stato più in grado di individuare problemi come questo avendo tutto incapsulato in classi e metodi. .com/rock-solid-rake-compiti.html potrebbe essere d'aiuto; mi ha aiutato – Matt