代码之家  ›  专栏  ›  技术社区  ›  Daisuke Shimamoto

使用“清除”方法与新对象

  •  34
  • Daisuke Shimamoto  · 技术社区  · 14 年前

    在.NET framework中,许多System.Collection类 Clear

    谢谢。

    5 回复  |  直到 14 年前
        1
  •  43
  •   Brian R. Bondy    14 年前

    你想用 Clear

    例如,您可能有一个工作队列,用于存储要执行的任务。在一个或多个线程中,您可以将工作项从队列中取出(当然,您可以使用锁定来确保一次最多使用一个线程访问队列)。如果在某个时候您想清空队列,那么您可以使用 清除

    作为 seen here 当你使用 所有项目将被删除,并且 Count 将为0,但 Capacity 容量 保持不变是一件好事(为了提高效率),但可能会出现一些极端情况,即您有大量的项,并且希望最终释放内存。

        2
  •  6
  •   Andrew Hare    14 年前

    布莱恩是对的,但更具体地说 Clear 方法从集合的当前实例中移除所有项。实例化一个新集合并将它的引用赋给您的变量将为您提供一个全新的实例,并且可能会导致一些意外的后果,这取决于其他人是否持有对旧实例的引用。如果另一个线程有一个对该集合的引用,那么即使您创建了一个新实例,它们仍然会保留对旧集合的引用。

        3
  •  3
  •   hallie    14 年前

        4
  •  3
  •   Oscar Cabrero    6 年前

    替换引用不会立即释放集合它需要等待垃圾收集器来处理对象,

    如果要重新利用同一个对象集合,请使用.Clear(),否则这两个对象将在内存中保留一段时间。

        5
  •  1
  •   Oğuzhan Türk    9 年前

    如果您处理大数据并且频繁地操作IEnumerable项,新对象会导致内存问题。看看我的例子:

    class Lol
    {
        int i;
        string s;
        public Lol(int ti, string ts)
        {
            i = ti;
            s = ts;
        }
    }
    
    class Program
    {
        static List<Lol> lol = new List<Lol>();
    
        static void Main(string[] args)
        {
            for (int i = 0; i < 10000000; ++i)
                lol.Add(new Lol(i, i.ToString()));
    
            Stopwatch sw = new Stopwatch();
            sw.Start();
            ListCleaner();
            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);
    
            for (int i = 0; i < 10000000; ++i)
                lol.Add(new Lol(i, i.ToString()));
    
            Console.WriteLine("lol");
    
            ListCleaner();
    
            for (int i = 0; i < 10000000; ++i)
                lol.Add(new Lol(i, i.ToString()));
    
            Console.WriteLine("lol");
    
            ListCleaner();
    
            for (int i = 0; i < 10000000; ++i)
                lol.Add(new Lol(i, i.ToString()));
    
            Console.WriteLine("lol");
    
            ListCleaner();
    
            for (int i = 0; i < 10000000; ++i)
                lol.Add(new Lol(i, i.ToString()));
    
            Console.WriteLine("lol");
    
            ListCleaner();
    
            for (int i = 0; i < 10000000; ++i)
                lol.Add(new Lol(i, i.ToString()));
    
            Console.WriteLine("lol");
    
            ListCleaner();
    
            for (int i = 0; i < 10000000; ++i)
                lol.Add(new Lol(i, i.ToString()));
    
            Console.WriteLine("lol");
    
            ListCleaner();
    
            for (int i = 0; i < 10000000; ++i)
                lol.Add(new Lol(i, i.ToString()));
    
            Console.WriteLine("lol");
    
            ListCleaner();
    
            for (int i = 0; i < 10000000; ++i)
                lol.Add(new Lol(i, i.ToString()));
    
            Console.WriteLine("lol");
    
            ListCleaner();
        }
    
        static void ListCleaner()
        {
            //lol = new List<Lol>();
            lol.Clear();
        }
    }
    

    顺便说一下“Console.WriteLine(sw.elapsedmilliskes);”(您可以使用ElapsedTicks,因为它的值与另一个明显不同。)行告诉您,清除需要更多的时间,但可以避免内存问题。

    我注意到所有这些都发生在调试代码上(甚至对于发布模式)。运行.exe文件没有问题。