我是面向对象代码的新手,如果这段代码是安全的,我有一个问题。 我有一个本地列表“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;
}
}
答案 0 :(得分:1)
我担心我的局部变量的内存会受到垃圾收集的影响
其中一个意味着无法收集垃圾的东西是,有一个正在使用的局部变量引用它。
然后会影响我的静态变量
另一个意味着无法收集垃圾的东西,就是有一个引用它的静态字段。
本地变量本身并不是垃圾收集所影响的东西;在该方法未使用它的某个时刻(可能是在保留范围时,或者可能在此之前),本地存储器可以仅用于其他东西。你几乎永远不会关心,因为如果你去使用它,那么根据定义你不会在它永远不会被使用的地方(有一个例外的计时器和弱引用,但你在这里都没有使用)
现在,如果该局部变量是一个引用类型,那么它可能是保持对象被引用的东西。但是,这通常不会被看到,因为只有当它是唯一对此对象的引用时才会显示。
当垃圾收集器启动时,它首先要做的是找到无法收集的所有内容:
如果你能“看到”它,GC就无法收集它。
GC不会影响您的静态字段,因为根据定义,处于静态字段会使其成为禁止值。
答案 1 :(得分:0)
TempCand
和Candidates
是对某些数据的引用(在这种情况下是Candidate
个对象的列表)。当然,您可以创建和销毁其他引用,而不会影响对象。
所以,一种可能的情况是:
您创建Candidates
列表并在其中放入5个Candidate
个对象。
由于列表引用了对象,并且静态属性引用了列表,因此不会对对象进行垃圾回收。
您调用CleanCandidates
静态方法。在其中,您可以为候选列表创建另一个引用(tempCand
)。您将对Candidate
个对象的引用添加到新列表中。
如果此时发生垃圾运行,则不会收集任何Candidate
个对象,因为它们仍会从静态列表中引用。
您设置静态Candidates
属性现在指向新列表并退出方法。如果现在发生垃圾运行,它可以收集
Candidates
过去引用的旧列表。它现在没有被任何引用。Candidate
对象,但不在新列表中,因为现在没有任何内容可以引用它们。tempCand
引用,因为它超出范围 - 方法已完成,如果再次调用它,将创建新引用。请注意,tempCand
引用的列表将不会被收集,因为它现在可以通过Candidates
静态字段获得。 (请注意,本地字段的集合通常使用堆栈倒带“神奇地”完成)所以,你想要活着的候选人将会(并保持活着),你扔掉的候选人最终将被垃圾收集(如果没有被其他人引用,则不会显示代码)。
也就是说,显示的代码不是线程安全的。您可能会执行两次CleanCandidates
,并对集合造成严重破坏。您必须非常非常小心,因为静态列表实际上是共享应用程序状态。