带有位图的C#内存泄漏

带有位图的C#内存泄漏,c#,memory-leaks,bitmap,C#,Memory Leaks,Bitmap,我正在用C#编写一个基于瓷砖的游戏。但我遇到了一个问题,当应用程序处于窗口模式时,我的系统内存大约在+-300MB左右振荡,在全屏模式下,它会耗尽所有内存并抛出OutOfMemoryException 据我所知,我找不到任何地方忘记了可能导致这种情况的.Dispose()东西 我能找到的最接近问题的地方是I.Clone()将位图复制到PictureBox.Image中。这种情况每帧发生一次。我在内存中渲染了整个“世界”,这是一个大约2000x1000像素的位图,我从中复制要在屏幕上显示的部分 我

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

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

我能找到的最接近问题的地方是I.Clone()将位图复制到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();
    }
通过查看相关问题(google没有告诉我!),我发现将此添加到Render()函数可以解决问题:

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

但是,我很想知道为什么也必须处理掉它。

当您克隆时,您创建了对象的副本。因此,新的
位图
对象最终也需要对其调用
Dispose

renderArea.Image = worldEditor.map.GetMap(area);
重新指定图像而不进行处理,因此泄漏旧对象。如果您从post in中添加代码,则会清理对象,解决问题

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

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

if (oldImage != null)
    oldImage.Dispose();

如果没有代码,这将很难帮助…为什么会被否决?很清楚他在问什么。@miliesmith否决票可能在代码发布之前就已经出现了added@BradleyDotNET我不认为是这样,因为当我点击这个问题时,代码已经被添加,没有投票。@milies没有任何线索,这是一个非常好的问题谢谢。我的印象是旧图像会被新图像覆盖,这显然是错误的。@user2790895是的,引用不是那样工作的:)是的,我知道引用,但我的意思是,当新图像出现时,旧图像将不再被引用,因此它不应该被垃圾收集吗?@user2790895确实如此,但是
Bitmap
包装了一个GDI位图,需要手动处理以及时释放大量未管理的对象。无论如何,位图应该由GC处理(在终结器中)。