2015-10-24 41 views
1

我有一個生成器,它將一系列簡單的翻譯效果應用於圖像Surface,使用pygame.surfarray.pixels2d()。然而,我很快發現,隨着循環的循環,Python的內存使用膨脹,最終拋出一個MemoryError並崩潰。如何防止pygame.surfarray.pixels2d中的內存泄漏?

在試圖原因隔離開來,我到達這個簡單的循環:

import pygame 
testsurf = pygame.Surface((1,1)) 
while True: # normally, this would be a generator. 
    testarray = pygame.surfarray.pixels2d(testsurf) 
    del testarray # only necessary if the Surface is blitted. 

無論這個代碼在實際的環境中運行(顯示具有有用的圖像內容的面,更新顯示,實際應用中的效果)或者作爲一個測試(運行pixels2d而不是別的),Python的內存使用量將大幅增長(大約4Mb /秒,並且快速到10Mb /秒,獨立於其他波動),直到它無法佔用更多。

如果我沒有將pygame.surfarray.pixels2d(testsurf)分配給變量,並且我沒有以任何方式改變它,這意味着使用沒有內存使用函數的唯一方法就是不使用氣球,而是按原樣調用它,沒有效果。這意味着我可以看看它,而沒有別的。即使是一個簡單的值分配,pygame.surfarray.pixels2d(testsurf)[0,0] = 0,也會導致內存問題。

我已經嘗試了許多不同的解決方案:

  • 在實際的測試中,使用testarray = pygame.surfarray.array2d(testsurf)代替pixels2d視圖,然後使用pygame.pixels2d(testsurf)[...] = testarray施加陣列回目標表面,
  • 改變testarray = pygame.surfarray.pixels2d(testsurf).copy()並將該陣列應用到目標表面,如上所示,
  • 使用pygame.surfarray.pixels2d(testsurf)代替testarray,以便視圖永遠不會分配給變量。
  • 在上述每一項中,添加或刪除del testarray都沒有效果。

在所有情況下,Python的內存使用(已報告給任務管理器)的增長實際上是不停,直到我關閉程序關閉/重新啓動IDLE,此時內存被釋放。如果循環暫停但外殼未關閉或重新啓動,則內存繼續保持。

我使用的是不正確的pixels2d?是否有一些我需要調用的函數觸發未發生垃圾回收?所有舊的對象被保存在某個地方而不是被重新分配或刪除(公開或在垃圾回收期間)?有些地方正在填滿陣列(或者其他一些數據,我想),我不知道在哪裏或如何,或者該怎麼做。

我正在使用Python2並安裝了NumPy

== UPDATE ==

它看起來像到視圖一些地方被保存引用:

from sys import getrefcount 
for n in range(25): 
    testarray = pygame.surfarray.pixels2d(testsurf) 
    del testarray 

>>> getrefcount(testsurf) 
... 27 

我還發現this鏈接從年前的那一條消息,該問題結束解決了pixels2d以及pixels3d,但在這裏。我的pygame版本是1.9.2pre;當然不是四歲。

== UPDATE ==

貌似testarray = numpy.array(testsurf.get_view())創建這些虛引用,所以它不一定與surfarray一個缺陷,但一些與曲面自己做...

+0

如果從命令行運行而不是使用IDLE,它會顯示相同的行爲嗎? – saulspatz

+0

@saulspatz它確實如此。 :C – Augusta

回答

0

這內存泄漏在Pygame的1.9.1release版本中得到糾正,或者至少是Python2.7/Windows版本。安裝此版本,問題就會消失。

1.9.2pre可能是模塊的實驗版本,從來沒有錯誤修補。在這個版本中嘗試和解決問題可能難以想象,因爲問題似乎在Pygame的Surface模塊中,(據我所知)實際上是C。爲了糾正它,它需要對組件進行逆向工程,糾正缺陷,然後重新打包它 - 不用說,除非你先寫了這個東西,然後再做更多的工作,而不僅僅是向上(向下)分級到1.9 (如果你仔細觀察the files on the Pygame downloads FTP link,你會發現實際上是半年或更多較新的比1.9.2pre)。它還解釋了在版本號的末尾有一點點「pre」。

** - 更新 - **

Here's the issue report,如果你喜歡這種東西。

相關問題