首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >局部变量和垃圾生成

局部变量和垃圾生成
EN

Stack Overflow用户
提问于 2013-08-18 17:12:08
回答 2查看 3.6K关注 0票数 5

我的代码中有一段被反复调用(每秒2000+)。为了避免垃圾生成和减少性能开销,我将所有局部变量移到类级别,但我不确定这种方法是否有效.

我的问题是..。

  • 当垃圾收集器正在收集局部变量时?
  • 将局部变量移到类级别是否会提高性能并减少垃圾生成?
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-08-18 20:28:54

考虑这个非常简单的例子(其中SomeObject是一个类,而不是一个结构):

代码语言:javascript
复制
class C
{
  void MethodCalledMillionsOfTimes()
  {
    var so = new SomeObject();
    // some use of so
  }
}

每次调用该方法时,都会在堆上创建一个新对象。它需要在它的使用结束一段时间后被垃圾收集。这是方法的每个调用要收集的一个对象。

然后假设它被更改为:

代码语言:javascript
复制
class C
{
  SomeObject soField;

  void MethodCalledMillionsOfTimes()
  {
    soField = new SomeObject();
    // some use of soField
  }
}

这什么都改变不了!仍然为每个方法调用创建一个新实例。垃圾收集器必须完成同样数量的工作。

但如果你这么做了呢

代码语言:javascript
复制
class C
{
  SomeObject soField = new SomeObject();

  void MethodCalledMillionsOfTimes()
  {
    // some use of soField
  }
}

这一次,每次在同一个实例上再次调用该方法时,都会重用相同的对象。因此,需要垃圾收集的对象就更少了(假设方法实际上在同一个C对象上被多次调用)。请注意,只有当SomeObject实例可以多次使用,并且状态没有被每次使用“破坏”时,这才能起作用。

如果多个线程同时调用该方法,请确保对象soField能够处理该方法。

如果你更进一步说:

代码语言:javascript
复制
class C
{
  static SomeObject soStaticField = new SomeObject();

  void MethodCalledMillionsOfTimes()
  {
    // some use of soStaticField
  }
}

然后,只有一个对象在C的所有实例之间共享。GC不需要收集任何SomeObject

但是,这个GC活动对您的性能通常并不重要。因此,请测量,如果它是重要的或不对您的情况。

票数 3
EN

Stack Overflow用户

发布于 2013-08-18 17:13:56

变量不是垃圾收集的。物体被垃圾收集..。它们可以在运行时检测到它们不再被任何活动代码引用之后的任何时间被垃圾收集。这可以包括局部变量引用的对象:

代码语言:javascript
复制
public void Foo()
{
    object x = new object();
    // The object can't be collected here...
    Console.WriteLine(x);
    // But it *can* be collected here
    Console.WriteLine("This line doesn't depend on x");
}

为了垃圾收集而改变“自然”的设计很少是个好主意.方法的状态通常不是对象状态的一部分,因此将局部变量转换为实例变量通常是个坏主意。

也就是说,我们不知道这些局部变量代表什么,也不知道关于它们的任何东西--我们需要更多的上下文来评论您的具体情况。

票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18301652

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档