【问题标题】:Static Methods Memory Consumption静态方法内存消耗
【发布时间】:2011-09-02 14:25:21
【问题描述】:

我有以下具有以下方法的类:

public class Foo
{
   public string A {get;set;}

   public static Foo New(string a)
   {
      Foo newFoo = new Foo();
      newFoo.A = a;
      return newFoo;
   }
 }

 public class Bar
 {
   public void SomeMethod()
   {
       ...
       Foo anotherFoo = Foo.New("a");
       ....
   }
 }

如果 Bar 类在使用上述代码的过程中创建 Foo,Foo 是否会超出范围并被垃圾收集,或者 Foo(因为它使用静态方法)会继续引用变量 newFoo 并因此引用另一个Foo永远不会超出范围?

【问题讨论】:

    标签: c# memory static


    【解决方案1】:

    静态方法的存在不会影响对象的 GC 资格,只有对该对象的引用会影响。在您的情况下,anotherFoo 将是唯一的参考。当方法返回时,引用 newFoo 超出范围,从堆栈中弹出。

    静态方法中的局部变量本身并不是“静态的”,当方法返回时,这些局部变量会像非静态方法一样从执行堆栈中弹出。

    anotherFoo 背后的底层对象将在SomeMethod 返回时符合 GC 条件(好吧,编译器更具侵略性,并且可以在代码中不再使用 anotherFoo 时使其能够进行 GC)。

    【讨论】:

      【解决方案2】:

      aFoo.New() 完成后立即离开范围。返回对newFoo 的引用,然后newFoo 超出范围。 SomeMethod 仍然通过anotherFoo 引用对该实例进行引用,因此在SomeMethod 完成之前,该引用不可用于垃圾收集,除非该引用被保存。

      【讨论】:

        【解决方案3】:

        类永远不会“超出范围”。实例(参考)做。至于 newFoo 引用,当 New 方法结束时它会超出范围,而 anotherFoo 在 SomeMethod 方法结束时也会超出范围。

        该方法是静态的这一事实并没有改变任何东西,事实上,你甚至可以在 Foo 中有一个静态变量它不会改变任何东西,因为静态变量是在一个称为“高频堆”的单独堆上创建的,其中GC 显然从不收集任何东西。

        【讨论】:

          猜你喜欢
          • 2015-11-14
          • 2017-12-07
          • 1970-01-01
          • 2013-02-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-12
          • 1970-01-01
          相关资源
          最近更新 更多