2012-11-29 69 views
2

我有一個Python代碼的特定情況。每次運行代碼時,RAM內存都會增加,直到達到1.8 GB並崩潰。Python 2.7.3內存錯誤

import itertools 
import csv 
import pokersleuth 

cards = ['2s', '3s', '4s', '5s', '6s', '7s', '8s', '9s', 'Ts', 'Js', 'Qs', 'Ks', 'As', '2h', '3h', '4h', '5h', '6h', '7h', '8h', '9h', 'Th', 'Jh', 'Qh', 'Kh', 'Ah', '2c', '3c', '4c', '5c', '6c', '7c', '8c', '9c', 'Tc', 'Jc', 'Qc', 'Kc', 'Ac', '2d', '3d', '4d', '5d', '6d', '7d', '8d', '9d', 'Td', 'Jd', 'Qd', 'Kd', 'Ad'] 
flop = itertools.combinations(cards,3) 

a1 = 'Ks' ; a2 = 'Qs' 
b1 = 'Jc' ; b2 = 'Jd' 

cards1 = a1+a2 
cards2 = b1+b2 

number = 0 
n=0 
m=0 

for row1 in flop: 
    if (row1[0] <> a1 and row1[0] <>a2 and row1[0] <>b1 and row1[0] <>b2) and (row1[1] <> a1 and row1[1] <>a2 and row1[1] <>b1 and row1[1] <>b2) and (row1[2] <> a1 and row1[2] <> a2 and row1[2] <> b1 and row1[2] <> b2): 
     for row2 in cards: 
      if (row2 <> a1 and row2 <> a2 and row2 <> b1 and row2 <> b2 and row2 <> row1[0] and row2 <> row1[1] and row2 <> row1[2]): 
       s = pokersleuth.compute_equity(row1[0]+row1[1]+row1[2]+row2, (cards1, cards2)) 
       if s[0]>=0.5: 
        number +=1 
        del s[:] 
       del s[:] 

     print number/45.0 
     number = 0 
     n+=1 
+3

'del s [:]'的意圖是什麼?這是刪除一個新創建的副本。 –

+0

試圖刪除列表,因爲我在哪裏數據去。我不保存任何東西,只是打印結果。 –

+2

聖牛,誰寫這意大利麪條。另外,'pokersleuth.compute_equity()'做了什麼?你不需要刪除列表,btw ... – kreativitea

回答

1

你在 Linux上運行(是嗎?),和你打你的系統的最大處理圖像的大小,因爲Linux的進程不能減少其內存大小。 窗口。

你的選擇是拆分它,以便它可以在達到內存限制後恢復,編譯內核的進程大小限制更高 ,或者在windows上運行

+1

好點,Marcin!不過,我在Windows上運行它。這個問題仍然存在於這個系統上嗎? –

+0

@TomBaker在這種情況下,可能是(a)您使用的代碼存在問題,或者(b)您的代碼需要大量內存,因爲Windows進程可能會縮小。 – Marcin

2

我的內存泄漏發生的測試是不確定的,但假設它並沒有發生在montecarlo.dll中,我想我會嘗試multiprocessing.Pool()並將工作分成更小的塊,我卸載到某些進程在開始使用過多內存之前我可以終止:

from itertools import combinations, product, islice 
from multiprocessing import Pool 
from pokersleuth import compute_equity 

num_procs = 4 
num_jobs = 256 
chunk_size = num_procs * num_jobs 

join = ''.join 

drawn = a1, a2, b1, b2 = 'Ks', 'Qs', 'Jc', 'Jd' 
pairs = (a1 + a2, b1 + b2) 

deck = (join(reversed(c)) for c in product('shcd', '23456789TJQKA')) 
deck = [card for card in deck if card not in drawn] 

def compute_chances(cards): 
    return sum(compute_equity(cards + card, pairs)[0] >= 0.5 
       for card in deck if card not in cards)/45.0 

if __name__ == '__main__': 
    combis = (join(each) for each in combinations(deck, 3)) 
    i = 0 
    while True: 
     pool = Pool(processes=num_procs) 
     chunk = list(islice(combis, chunk_size)) 
     for i, chances in enumerate(pool.imap(compute_chances, chunk), i + 1): 
      print i, chances 
     pool.terminate() 
     if len(chunk) < chunk_size: 
      break 

結果與程序中的結果相同。

這裏是任務管理器中說,有關內存消耗的17最後7圈(17296組合,帶1024 chunk_size):

10 loops

每個迴路使用了大約400 MB,並花了34個miuntes到處理所有組合。

而不是在卡整個甲板手動鍵入,我有計算機創建對我來說。我拒絕做計算機可以做的事情。

爲了使傳遞到儘可能小的每個進程的數據量,我只有三張牌每個組合發送到compute_chances(),並擁有一切計算存在。

如果montecarlo.dll是折返,但結果似乎表明,它是我不是舒爾。

在我的代碼num_procsnum_jobs值在我的機器上運行良好。你應該和他們一起玩,爲你找到最佳的設置。