Python内存泄漏

0 投票
2 回答
955 浏览
提问于 2025-04-17 04:51

我有一个叫做'cell'的对象数组,创建方式如下:

class Cell:
  def __init__(self, index, type, color):
    self.index = index
    self.type = type
    self.score = 0
    self.x = index%grid_size
    self.y = int(index/grid_size)
    self.color = colour


alpha = 0.8
b = 2.0
grid_size = 100
scale = 5

number_cells = grid_size*grid_size
num_cooperators = int(number_cells*alpha)       
cells = range(number_cells)
random.shuffle(cells)
cooperators = cells[0:num_cooperators]
defectors = cells[num_cooperators:number_cells]
cells = [Cell(i, 'C', blue) for i in cooperators]
cells += [Cell(i, 'D', red) for i in defectors]
cells.sort(compare)

我在一个循环中像这样获取它们的属性:

while 1:
    pixArr = pygame.PixelArray(windowSurfaceObj)
    for cell in cells:
        x = cell.x
        y = cell.y
        color = cell.color
        for y_offset in range(0,scale):
            for x_offset in range(0,scale):
                pixArr[x*scale + x_offset][y*scale + y_offset] = color
    del pixArr
    pygame.display.update()

我发现内存使用得很疯狂...这是怎么回事呢?

2 个回答

0

Cell类可以通过使用槽来节省内存空间。这样做应该能大幅减少内存的使用:

class Cell(object):
    __slots__ = ('index', 'type', 'color')
    ...

你代码中唯一比较大的结构是pixArr。你可能想用sys.getsizeof来查看它的大小。另一个可以帮助你找出内存泄漏的工具是美化打印gc.garbage

1

在PixelArray中似乎有一个bug。

下面的代码通过每次循环只设置一个像素来重现内存泄漏的问题,而且你甚至不需要更新显示就能引发这个问题:

import pygame, sys
from pygame.locals import *
ScreenWidth, ScreenHeight = 640, 480
pygame.init()
Display = pygame.display.set_mode((ScreenWidth,ScreenHeight), 0, 32)
pygame.display.set_caption('Memory Leak Test')
while True:
    PixelArray = pygame.PixelArray(Display)
    PixelArray[ScreenWidth-1][ScreenHeight-1] = (255,255,255)
    del PixelArray
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
#pygame.display.update()

如果你能接受性能下降,可以用(非常短的)线条替代直接设置像素,这样就能避免内存泄漏,比如:pygame.draw.line(Display, Colour, (X,Y), (X,Y), 1)

撰写回答