2012-09-05 48 views
14

我有一個複雜的python服務器應用程序,它始終運行不斷。下面是它的一個非常簡化的版本。pypy內存使用會永遠增長嗎?

當我使用python運行下面的應用程序; 「python Main.py」。它直接使用8mb的ram,並且應該保持在8mb的ram。

當我運行它使用pypy「pypy Main.py」。它開始使用22MB的內存,並隨着時間的推移使用內存的增長。在30分鐘後,它在50mb,一小時後在60mb。

如果我將「b.something()」更改爲「pass」,它不會吞噬那樣的內存。

我在OSX上使用pypy 1.9 10.7.4 我很喜歡使用比python更多的ram。

有沒有一種方法可以阻止長時間吃掉記憶的pypy?

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) 

下面是一個時間列表和當時的RAM的使用(我離開它運行在夜間)。

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

嗯。我無法重現這一點。使用pypy 1.9(來自Macports)和OS X 10.6.8,我發現內存使用量(由RSIZE專欄中的'top'報道)保持在46M左右。這可能是值得一個錯誤報告。 –

+0

我仍然有這個過程運行,它的新數據點: Thu Sep 6 09:02:26 2012,63mb ram – DavidColquhoun

+2

我可以使用pypy 1.8重現此問題,但1.9似乎已經糾正了此問題 – goncalopp

回答

10
+0

哎呀,評論錯誤的回覆,將我的評論移至上述答案。 – DavidColquhoun

+2

4個月後,我意識到羅尼連接的是更好的解決方案。設置PYPY_GC_MIN = 1GB和PYPY_GC_MAX = 3GB可以更好地保持內存使用量在1到3 GB之間。我發現gc.collect()調用花費了大約50ms的時間......我的應用程序太慢了。所以,那些環境變量是一個更好的方法。 :) – DavidColquhoun

+0

@DavidColquhoun是'PYPY_GC_MIN = 1GB'和'PYPY_GC_MAX = 3GB',而不是'PYPY_GC_MIN =「1GB」'和'PYPY_GC_MAX =「3GB」',對嗎? –

5

相比CPython的,pypy使用different garbage collection strategies。 如果內存增加是由程序中的某些內容引起的,那麼可以嘗試使用gc模塊中的collect函數來不時運行強制垃圾回收。在這種情況下,它也可能有助於明確地指定del不再需要的大對象,並且這些對象不會超出範圍。正如Mark Dickinson所建議的那樣,如果是由於pypy的內部工作原因,可能值得提交bug報告。

+0

謝謝! gc.collect()是我所需要的。我每隔幾秒就會運行一次,並保持內存使用率不變......查看這裏的圖表,查看一個命令的差異:http://datasmugglers.com/2012/10/06/server-ram-usage/ – DavidColquhoun