CSharp内存分配

问题描述 投票:0回答:1

今天在尝试优化时遇到了一件比较奇怪的事情。我使用 Monogame 框架并想即时创建纹理。我在 Visual Studio Community 2022 中使用 .NET 6。

所以这是执行此操作的直接代码,工作正常:

    public static Texture2D CreateTexture(GraphicsDevice graphicsDevice, int width, int height)
    {
        Texture2D tex = new(graphicsDevice, width, height, true, SurfaceFormat.Color);
        Color color = new((byte)255, (byte)255, (byte)255, (byte)255);
        int length = width * height;
        Color[] colorArray = new Color[length];

        for (int i = 0; i < length; i++)
        {
            color.A = (byte)randomizer.Next(0, 256);
            colorArray[i] = color;
        }

        tex.SetData<Color>(colorArray);

        return tex;

    }

由于我多次调用这个方法,通常是相同的宽度和高度,我想我可以做一些内存优化,最后得到类似的代码:

    static int texW = 1;
    static int texH = 1;
    static Color[] colorArray = new Color[1];

    public static Texture2D CreateTexture2(GraphicsDevice graphicsDevice, int width, int height)
    {
        Texture2D tex = new(graphicsDevice, width, height, true, SurfaceFormat.Color);
        int length = width * height;

        if (texW != width || texH != height)
        {
            texW = width;
            texH = height;
            colorArray = new Color[length];
        }

        for (int i = 0; i < length; i++)
        {
            colorArray[i].A = (byte)randomizer.Next(0, 256);
            colorArray[i].R = 255;
            colorArray[i].G = 255;
            colorArray[i].B = 255;
        }

        tex.SetData<Color>(colorArray);

        return tex;
    }

如您所见,我尽量避免在每次调用函数时都分配 colorArray。由于数组是 Color-struct-objects 的列表,我假设我应该用 new 替换每个结构对象中的 R、G、B 和 A 值,而不是替换整个结构。

为了测试它,我尝试在单独的调试会话中每秒调用这两个函数数千次,每次大约三十秒。

我希望我的改变能改善各种与记忆相关的事情,但没有!相反,我的第二个例子真的让垃圾收集器感到不安,它开始频繁地进行 GC,视觉工作室的“诊断工具”显示分配的对象是原来的两倍,而且帧率似乎也下降了。

有人知道这里发生了什么吗?我的第二个代码示例分配了 colorArray one 时间,正如我用相同的宽度和高度调用它数千次时所预期的那样。此外,为字节类型的 R、G、B 和 A 成员赋值不应导致任何内存分配。

c# garbage-collection monogame
1个回答
0
投票

正如杰里米在评论中指出的那样,罪魁祸首是 Texture2D。在我的测试代码中绘制纹理后,我没有在纹理上调用 Dispose()。不好意思,怪我看不懂文档

现在,当我调用 Dispose() 时,代码按预期工作。但是我对这两段代码之间的微小差异感到有点惊讶;为什么第一段代码不会比它更让 GC 不安?在我的简单测试中,我看不出真正的区别。

© www.soinside.com 2019 - 2024. All rights reserved.