应用程序内存不足,同时将纹理保存到PNG文件

时间:2019-07-16 22:32:25

标签: c# xna

我每帧都在RenderTarget2D对象上使用SaveAsPng()。我也在每帧上都处理了RenderTarget2D和输入流。但是,在保存大约500张图像之前,我收到一条消息,指示该应用程序内存不足。

我在调用Dispose()时尝试进行更改,但是每次都得到相同的结果。

RenderTarget2D rt;

protected override void Update(GameTime gameTime)
    {
    if (rt != null)
        {
        rt.Dispose();
        }

    rt = new RenderTarget2D(GraphicsDevice, graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight);

    GraphicsDevice.SetRenderTarget(rt);
    GraphicsDevice.Clear(Color.Transparent);

    sb.Begin();
    //I draw stuff here.
    sb.End();

    GraphicsDevice.SetRenderTarget(null);
    GraphicsDevice.Clear(Color.Black);

    Stream stream = File.Create(path);
    rt.SaveAsPng(stream, graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight);
    stream.Dispose();
    stream.Close();
    }

我希望这样做是释放与前一帧上绘制的图片相关联的内存,为新的RenderTarget2D分配新的内存空间,这样,仅使用与存储单个图像相同的内存即可。在画画。我认为,出于某种原因,所有图像都存储在内存中,直到空间用完。 (该错误是由SaveAsPng方法调用生成的,根据VS,内存使用情况似乎与运行时间呈线性关系,而在应用程序中什么也没有,除了这个小的图像处理位会占用大量内存。)

更新: 这是我第一次使用内存快照,所以我一定在看错这个地方,但是对我来说,似乎左侧的数据似乎无法反映右侧的内存使用情况图。

Snapshot Comparison

2 个答案:

答案 0 :(得分:0)

不进行概要分析很难弄清楚。尝试使用Visual Studio拍摄内存快照,并确定存储内存的位置。

https://docs.microsoft.com/en-us/visualstudio/profiling/memory-usage?view=vs-2019

答案 1 :(得分:0)

我有几点想法。

首先,建议将using构造与File.Create一起使用,因为这样可以为您进行清理(see the examples here),例如:

using (Stream stream = File.Create(path)) {
  rt.SaveAsPng(stream, graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight);
}

这将确保流得到正确处理。

我的下一个想法是,Update()的调用非常频繁,因此您可能不知所措。由于图像将变得相对较大,因此C#可能根本无法及时释放内存。

也许您应该限制图像的保存速度(也许每0.5秒一次)。那么,如果您以某种方式泄漏内存或只是使垃圾收集器不堪重负,这将更加明显。

希望有帮助。