一尘不染

没有可用的内存时,.Net和位图不会由GC自动处置

c#

我想知道在.NET中如何为位图分配和分配内存。

当我在一个函数的循环中创建大量位图并连续调用它时,它将起作用,直到某个时候位图将无法分配内存,并为指定的大小提供了“无效参数”。

如果我从垃圾回收器到垃圾回收器调用它的工作。

使用以下代码,您可以重新排除该错误:

class BitmapObject {
    public bool Visible {
        get { return enb; }
        set { enb = value; }
    }
    private bool enb;
    private Bitmap bmp;
public BitmapObject(int i, bool en)
{
    enb = en;
    bmp = new Bitmap(i, i);


   }
}

class Pool<T> where T : BitmapObject
{
    List<T> preallocatedBitmaps = new List<T>();
public void Fill() {
    Random r = new Random();
    for (int i = 0; i < 500; i++) {
        BitmapObject item = new BitmapObject(500, r.NextDouble() > 0.5);
        preallocatedBitmaps.Add(item as T);
    }
}

public IEnumerable<T> Objects
{
    get
    {
        foreach (T component in this.preallocatedBitmaps)
        {
            if (component.Visible)
            {
                yield return (T)component;
            }
        }


     }
    }
}

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
{
    for (int i = 0; i < 10; i++ )
    {
        Test();

            // without this it breaks
            //GC.Collect();
            //GC.WaitForPendingFinalizers();
        }

        Console.ReadKey();
    }

    private static void Test() {
        Pool<BitmapObject> pool = new Pool<BitmapObject>();
        pool.Fill();

        for (int i = 0; i < 100; i++)
        {
            var visBitmaps = pool.Objects;
            // do something
        }       
     }
}

阅读 224

收藏
2020-05-19

共1个答案

一尘不染

.NET Bitmap类“封装了GDI
+位图”,这意味着您应该DisposeBitmap完成后调用a ,

“在释放对图像的最后一个引用之前,请始终调用Dispose。否则,直到垃圾收集器调用Image对象的Finalize方法之前,它所使用的资源才会被释放。”

2020-05-19