C#位图内存泄漏

本文关键字:泄漏 内存 位图 | 更新日期: 2024-09-25 23:19:28

我正在用C#编写一个基于tile的游戏。但我遇到了一个问题,当应用程序处于窗口模式时,我的系统内存会振荡大约+-300MB,而在全屏模式下,它会耗尽所有内存并抛出OutOfMemoryException。

据我所知,我找不到任何地方可以忘记可能导致这种情况的.Dispose()。

我能找到的最接近问题的地方是将位图克隆到PictureBox.Image中。这种情况每帧发生一次。我在内存中渲染了整个"世界",这是一个大约2000x1000像素的位图,我从中复制要显示在屏幕上的部分。

我可以附加代码,但由于代码太多,我会等到问题明确后再加,而不是在上面的方法中。

感谢

编辑:这就是我认为问题所在:

public Bitmap GetMap(Rectangle renderedArea)
    {
        if (renderedArea.Bottom > renderedMap.Height || renderedArea.Right > renderedMap.Width)
            return renderedMap.Clone(new Rectangle(0,0,renderedMap.Width,renderedMap.Height),renderedMap.PixelFormat);
        return renderedMap.Clone(renderedArea, renderedMap.PixelFormat);
    }
public void Render(Rectangle area)
    {      
        renderArea.Image = worldEditor.map.GetMap(area);
        Graphics g = Graphics.FromImage(renderArea.Image);
        PointF stringPoint = MouseInputEventHandler.CursorLocation.ToCoords(worldEditor.map.TileArray.TileSize,worldEditor.RENDER_START);
        g.DrawString(string.Format("{0},{1}", (int)stringPoint.X, (int)stringPoint.Y), new Font("Arial",15,FontStyle.Bold), Brushes.Yellow, new PointF(6, 6));
        g.Dispose();
    }

通过查看相关问题(谷歌没有向我展示!),我发现将其添加到Render()函数中可以解决问题:

if (renderArea.Image != null)
            renderArea.Image.Dispose();

然而,我很想听听为什么这也必须处理掉。

C#位图内存泄漏

Clone时,创建对象的副本。因此,您的Bitmap对象最终也需要调用Dispose

renderArea.Image = worldEditor.map.GetMap(area);

重新指定图像而不进行处理,因此会泄漏旧对象。如果你在中添加了你的帖子中的代码,你就清理了对象,解决了你的问题。

一种可能更清晰的写作方式是:

Bitmap oldImage = renderArea.Image;
renderArea.Image = worldEditor.map.GetMap(area);
if (oldImage != null)
    oldImage.Dispose();