static variable =本地临时变量然后在c#中返回 - 这样安全吗?

时间:2015-12-02 16:23:17

标签: c# variables static local assign

我是面向对象代码的新手,如果这段代码是安全的,我有一个问题。 我有一个本地列表“TempCand”,分配给该类的静态成员列表“候选人”。当我离开搜索方法时,我担心我的局部变量的内存会受到垃圾收集的影响,这会影响我的静态变量。或者这样可以吗?

public class search
{
    class candidate
    {
        // ...
    }
    static List <candidate> Candidates = new List <candidate>();

    static public void clean_Candidates()
    {
        List <candidate> TempCand = new List <candidate>();
        // ...
        // copy some elements of Candidates in clean_Candidates()
        // ...
        Candidates = TempCand;
    }
}

2 个答案:

答案 0 :(得分:1)

  

我担心我的局部变量的内存会受到垃圾收集的影响

其中一个意味着无法收集垃圾的东西是,有一个正在使用的局部变量引用它。

  

然后会影响我的静态变量

另一个意味着无法收集垃圾的东西,就是有一个引用它的静态字段。

本地变量本身并不是垃圾收集所影响的东西;在该方法未使用它的某个时刻(可能是在保留范围时,或者可能在此之前),本地存储器可以仅用于其他东西。你几乎永远不会关心,因为如果你去使用它,那么根据定义你不会在它永远不会被使用的地方(有一个例外的计时器和弱引用,但你在这里都没有使用)

现在,如果该局部变量是一个引用类型,那么它可能是保持对象被引用的东西。但是,这通常不会被看到,因为只有当它是唯一对此对象的引用时才会显示。

当垃圾收集器启动时,它首先要做的是找到无法收集的所有内容:

  1. 正在使用的局部变量中的任何内容。
  2. 静态领域中的任何东西。
  3. 无法收集上述两条规则所述的对象字段中的任何内容。
  4. 规则3中的任何字段都无法收集,递归应用此规则。
  5. 如果你能“看到”它,GC就无法收集它。

    GC不会影响您的静态字段,因为根据定义,处于静态字段会使其成为禁止值。

答案 1 :(得分:0)

TempCandCandidates是对某些数据的引用(在这种情况下是Candidate个对象的列表)。当然,您可以创建和销毁其他引用,而不会影响对象。

所以,一种可能的情况是:

  1. 您创建Candidates列表并在其中放入5个Candidate个对象。 由于列表引用了对象,并且静态属性引用了列表,因此不会对对象进行垃圾回收。

  2. 您调用CleanCandidates静态方法。在其中,您可以为候选列表创建另一个引用(tempCand)。您将对Candidate个对象的引用添加到新列表中。

  3. 如果此时发生垃圾运行,则不会收集任何Candidate个对象,因为它们仍会从静态列表中引用。

  4. 您设置静态Candidates属性现在指向新列表并退出方法。如果现在发生垃圾运行,它可以收集

    • Candidates过去引用的旧列表。它现在没有被任何引用。
    • 旧列表中的两个Candidate对象,但不在新列表中,因为现在没有任何内容可以引用它们。
    • tempCand引用,因为它超出范围 - 方法已完成,如果再次调用它,将创建新引用。请注意,tempCand引用的列表将不会被收集,因为它现在可以通过Candidates静态字段获得。 (请注意,本地字段的集合通常使用堆栈倒带“神奇地”完成)
  5. 所以,你想要活着的候选人将会(并保持活着),你扔掉的候选人最终将被垃圾收集(如果没有被其他人引用,则不会显示代码)。

    也就是说,显示的代码不是线程安全的。您可能会执行两次CleanCandidates,并对集合造成严重破坏。您必须非常非常小心,因为静态列表实际上是共享应用程序状态。