使用 out 参数时 CLR 的行为如何,方法 returns 后垃圾收集器的作用是什么?

How does the CLR behaves while using an out paramerter, what is the role of garbage collector as soon as the method returns?

为了更具体,请看下面的代码片段。

    // Consider the itemCollection has list of items
    // Consider the classItems is CollectionClass that is manipulated from somewhere
    foreach(var item in itemCollection)
    {
      List<string> someNameCollection;
      bool complete = false;
      // itemCollection will be have thousand of items
      // First parameter is single item and item.AnyItems means IEnumerable<AnyItem>
      // classItems is CollectionClass that is manipulated from somewhere
      if(DoSomething(item , item.Items, classItems, out someNameCollection , out complete )){
// if someNameCollection will be empty i will fill it in DoSomework() using the same foreach() logic that is used in DoSomething()
        DoSomework(someNameCollection, complete); 
      }
    }


    private bool DoSomething(Item item, IEnumerable<AnyItem> anyItems, CollectionClass classItems, out List<string> nameCollection, out bool complete )
    {
      bool isNeeded = false;
      complete = false;
      nameCollection = new List<string>();

      // loop for some parameter supplied, loop will run for 100k items
      foreach(var item in anyItems)
      {
         // may be isNeeded true here
         isNeeded = true;
         //if true break the loop
         // complete == true,  may be here
      }

      if(!isNeeded)
      {
        foreach(var item in classItems)
       {
         // item are any name string
         nameCollection.Add(item);
       }
      }
      // another loop doing something
      foreach()
      {
         // uses the nameCollection here depending upon
      }

       foreach(var item in nameCollection)
       { 
          foreach()
         {
           // play with other things here
           // do some manipulations
           // may be, isNeeded = true here, if true break
         }
       }

       // and isNeeded is either true or false will only be determined may be before the end of the method

       return isNeeded;
    }

现在的问题是,一旦 DoSomething() 方法 returns 它也填充了可用的 nameCollection 列表。我相信 nameCollection 不会在这里被自动垃圾收集,它会驻留在大对象堆中(会吗?),即使方法 returns 这个对象可能还没有从内存中释放(以前我有经历过这个)。现在再次在下一次调用 DoSomething() 时,nameCollection 将被填充并返回,它驻留在内存中并且不会被清除,尽管我们每次都创建一个新实例。

是否存在与我上面描述的相同的行为?如果不是,这里的行为是什么。如果那些集合对象驻留在内存中,我如何在不影响我的参数化列表的情况下刷新它?如果集合对象不驻留在内存中,out参数如何获取集合对象?

如果有人能在这里描述我的核心行为,我将不胜感激。我将非常乐意清除我的错误概念并添加正确的概念。

堆栈是您的 GC 之一 "roots"。在这种情况下,局部变量在调用代码的堆栈帧中正式声明(我们知道,因为 ldloca 只对正式声明的局部变量有意义——而不是堆栈上环境未声明的值),所以 GC 不会除了遍历堆栈框架检查局部变量(以及剩余堆栈 window,但这更复杂)之外,您无需做任何其他事情。归根结底,对于GC来说,这和方法里面的局部变量没什么区别:

SomeObject foo = new SomeObject();

附带说明:您的列表分配是多余且浪费的,可能只是:

List<string> nameCollection;
bool complete = false;
// DoSomething will be called thousand of times
if(DoSomething(out nameCollection, complete )){ // do the further task }

但是,如果是我,并且 DoSomething 被调用了数千次,我可能 在方法之外分配它,并将内容视为可丢弃的(在方法开始时调用 Clear()),并在 中传递列表 - 以避免大量列表/数组分配。