2012-09-05 3 views
14

Ho una complicata app Python Server, che viene eseguita costantemente tutto il tempo. Di seguito è una versione molto semplificata di esso.l'utilizzo di memoria pypy cresce per sempre?

Quando eseguo l'app in basso utilizzando python; "python Main.py". Usa subito 8mb di ram e rimane a 8mb di ram, come dovrebbe.

Quando lo eseguo utilizzando pypy "pypy Main.py". Inizia con 22mb di ram e col passare del tempo aumenta l'utilizzo di ram. Dopo 30 secondi a 50mb, dopo un'ora a 60mb.

Se cambio "b.something()" da "passare", non assorbe la memoria in quel modo.

Sto usando pypy 1.9 su OSX 10.7.4 Sto bene con pypy usando più ram di python.

Esiste un modo per fermare PyPy dal mangiare la memoria per lunghi periodi di tempo?

import sys 
import time 
import traceback 

class Box(object): 
    def __init__(self): 
     self.counter = 0 
    def something(self): 
     self.counter += 1 
     if self.counter > 100: 
      self.counter = 0 

try: 
    print 'starting...' 
    boxes = []  
    for i in range(10000): 
     boxes.append(Box()) 
    print 'running!' 
    while True: 
     for b in boxes: 
      b.something() 
     time.sleep(0.02) 

except KeyboardInterrupt: 
    print '' 
    print '####################################' 
    print 'KeyboardInterrupt Exception' 
    sys.exit(1) 

except Exception as e: 
    print '' 
    print '####################################' 
    print 'Main Level Exception: %s' % e 
    print traceback.format_exc() 
    sys.exit(1) 

Ecco un elenco di volte e l'utilizzo della RAM in quel momento (ho lasciato correre durante la notte).

Wed Sep 5 22:57:54 2012, 22mb ram 
Wed Sep 5 22:57:54 2012, 23mb ram 
Wed Sep 5 22:57:56 2012, 24mb ram 
Wed Sep 5 22:57:56 2012, 25mb ram 
Wed Sep 5 22:57:58 2012, 26mb ram 
Wed Sep 5 22:57:58 2012, 27mb ram 
Wed Sep 5 22:57:59 2012, 29mb ram 
Wed Sep 5 22:57:59 2012, 30mb ram 
Wed Sep 5 22:58:00 2012, 31mb ram 
Wed Sep 5 22:58:02 2012, 32mb ram 
Wed Sep 5 22:58:03 2012, 33mb ram 
Wed Sep 5 22:58:05 2012, 34mb ram 
Wed Sep 5 22:58:08 2012, 35mb ram 
Wed Sep 5 22:58:10 2012, 36mb ram 
Wed Sep 5 22:58:12 2012, 38mb ram 
Wed Sep 5 22:58:13 2012, 39mb ram 
Wed Sep 5 22:58:16 2012, 40mb ram 
Wed Sep 5 22:58:19 2012, 41mb ram 
Wed Sep 5 22:58:21 2012, 42mb ram 
Wed Sep 5 22:58:23 2012, 43mb ram 
Wed Sep 5 22:58:26 2012, 44mb ram 
Wed Sep 5 22:58:28 2012, 45mb ram 
Wed Sep 5 22:58:31 2012, 46mb ram 
Wed Sep 5 22:58:33 2012, 47mb ram 
Wed Sep 5 22:58:35 2012, 49mb ram 
Wed Sep 5 22:58:35 2012, 50mb ram 
Wed Sep 5 22:58:36 2012, 51mb ram 
Wed Sep 5 22:58:36 2012, 52mb ram 
Wed Sep 5 22:58:37 2012, 54mb ram 
Wed Sep 5 22:59:41 2012, 55mb ram 
Wed Sep 5 22:59:45 2012, 56mb ram 
Wed Sep 5 22:59:45 2012, 57mb ram 
Wed Sep 5 23:00:58 2012, 58mb ram 
Wed Sep 5 23:02:20 2012, 59mb ram 
Wed Sep 5 23:02:20 2012, 60mb ram 
Wed Sep 5 23:02:27 2012, 61mb ram 
Thu Sep 6 00:18:00 2012, 62mb ram 
+1

Hmm. Non riesco a riprodurre questo. Con pypy 1.9 (da Macports) e OS X 10.6.8, vedo l'utilizzo della memoria (come riportato da 'top', dalla colonna RSIZE) rimanere a circa 46M. Potrebbe valere la pena di segnalare un bug. –

+0

Ho ancora in esecuzione quel processo, nuovo punto dati per questo: gio 6 set 09:02:26 2012, ram 63mb – DavidColquhoun

+2

Posso riprodurlo usando pypy 1.8, ma 1.9 sembra aver corretto questo problema – goncalopp

risposta

10
+0

Oops, ha commentato la risposta sbagliata, spostato il mio commento alla risposta di cui sopra. – DavidColquhoun

+2

4 mesi dopo e ho capito che ciò a cui Ronny si è collegato è una soluzione ancora migliore. L'impostazione di PYPY_GC_MIN = 1 GB e PYPY_GC_MAX = 3 GB funziona molto meglio, mantenendo l'utilizzo della ram tra 1 e 3 GB. E ho scoperto che le chiamate a gc.collect() richiedevano circa 50ms ... rallentando troppo la mia applicazione. Quindi sì, quelle variabili d'ambiente sono un modo molto migliore di andare. :) – DavidColquhoun

+0

@DavidColquhoun che è 'PYPY_GC_MIN = 1GB' e' PYPY_GC_MAX = 3GB', non 'PYPY_GC_MIN =" 1GB "' e 'PYPY_GC_MAX =" 3GB "', corretto? –

5

Rispetto al CPython, PyPy utilizza different garbage collection strategies. Se l'aumento di memoria è dovuto a qualcosa nel programma, è possibile provare a eseguire una garbage collection forzata di tanto in tanto, utilizzando la funzione collect dal modulo gc. In questo caso, potrebbe anche aiutare a specificare esplicitamente gli oggetti grandi di cui non hai più bisogno e che non escono dall'ambito.

Se è dovuto al funzionamento interno di pypy, potrebbe valere la pena di presentare un bug report, come suggerito da Mark Dickinson.

+0

Grazie! gc.collect() era ciò di cui avevo bisogno. Lo eseguo ogni pochi secondi e mantiene l'utilizzo della memoria piatto ... controlla il grafico qui per vedere la differenza che un comando ha fatto: http://datasmugglers.com/2012/10/06/server-ram-usage/ – DavidColquhoun