C#,XNA,FileStream,内存不足异常

时间:2011-12-16 11:26:08

标签: c# out-of-memory xna-4.0

我正在尝试将我的XNA游戏的每个渲染帧保存到硬盘。所以在每一帧中,我都会调用这段代码:

        protected override void LoadContent()
        {
            ....
            colorRT = new RenderTarget2D(GraphicsDevice, backbufferWidth, backbufferHeight, false, SurfaceFormat.Color, DepthFormat.Depth24);
            lightRT = new RenderTarget2D(GraphicsDevice, backbufferWidth, backbufferHeight, false, SurfaceFormat.Color, DepthFormat.None);
            specRT = new RenderTarget2D(GraphicsDevice, backbufferWidth, backbufferHeight, false, SurfaceFormat.Color, DepthFormat.None);

            ....
         }


        using (Stream stream = File.OpenWrite("color_"+frameNumber+".png"))
        {
            colorRT.SaveAsPng(stream, colorRT.Width, colorRT.Height);
            stream.Flush();
            stream.Close();
            stream.Dispose();
        }
        using (Stream stream = File.OpenWrite("light_" + frameNumber + ".png"))
        {
            lightRT.SaveAsPng(stream, lightRT.Width, lightRT.Height);
            stream.Flush();
            stream.Close();
            stream.Dispose();
        }
        using (Stream stream = File.OpenWrite("spec_" + frameNumber + ".png"))
        {
            specRT.SaveAsPng(stream, specRT.Width, specRT.Height);
            stream.Flush();
            stream.Close();
            stream.Dispose();
        }
        System.GC.Collect();
        frameNumber++;

但是如果这个代码打开了,内存消耗会上升和上升,大约半分钟后我会得到一个outOfMemory异常。我添加了flush,close,dispose和GC调用来尝试解决问题,但它并没有改变。

任何人都知道我做错了什么?

3 个答案:

答案 0 :(得分:5)

根据this Texture2D.SaveAsJpeg(以及Texture2D.SaveAsPng)内存泄漏。

解决方案(不幸的是)创建自己的纹理保存例程。

答案 1 :(得分:4)

听起来如果你为每一帧(即每秒很多)执行此操作,那么你正在编写3个图像 - 可能有一个队列正在构建将其写入磁盘,而这正在备份,程序运行的次数越多问题。

答案 2 :(得分:0)

强制GC.Collect只会收集有资格收集的内容......如果内存压力很高,GC算法会更频繁地为您执行此操作,因此很少< / strong>解决方案。

它还表明您认为Stream s = File.Open部分是问题所在。这包含在using语句中,之后立即超出范围,这意味着它被正确处理,也可能保留为Gen-0对象 - 这意味着GC快速,高效地收集。 / p>

您还有两个问题区域:用于调用保存到PNG的xxRT变量,以及每帧保存三个PNG的行为。

另外,您可以改进代码的格式:

    using (Stream stream = File.OpenWrite("color_"+frameNumber+".png"))
    using (Stream stream2 = File.OpenWrite("light_" + frameNumber + ".png"))
    using (Stream stream3 = File.OpenWrite("spec_" + frameNumber + ".png"))
    {
        colorRT.SaveAsPng(stream, colorRT.Width, colorRT.Height);
        lightRT.SaveAsPng(stream2, lightRT.Width, lightRT.Height);
        specRT.SaveAsPng(stream3, specRT.Width, specRT.Height);
    }