1.如果我有类似 Foo o = new Foo();在方法内部,这样做
意味着每次计时器滴答作响,
我正在创建一个新对象和一个新对象
引用那个对象?
是的。
2.如果我有字符串 foo = null 然后我只是在 foo 中放了一些临时的东西,
和上面一样吗?
如果你问行为是否相同,那么是的。
3.垃圾收集器是否曾经删除对象和引用或
对象被不断地创建和
留在记忆中?
这些对象使用的内存肯定是在引用被认为未使用后收集的。
4.如果我只是声明 Foo o;而不是指向任何实例,不是吗
方法结束时释放?
不,因为没有创建对象,所以没有要收集的对象(dispose 不是正确的词)。
5.如果我想确保所有内容都被删除,最好的方法是什么
这样做
如果对象的类实现了IDisposable,那么你肯定想尽快贪婪地调用Dispose。 using 关键字使这更容易,因为它以异常安全的方式自动调用 Dispose。
除了停止使用该对象之外,您实际上不需要做任何其他事情。如果引用是一个局部变量,那么当它超出范围时,它将有资格被收集。1 如果它是一个类级别的变量,那么您可能需要将 null 分配给它以使其在包含类符合条件之前符合条件。
1这在技术上是不正确的(或者至少有点误导)。一个对象在超出范围之前就可以被收集。 CLR 被优化为在检测到不再使用引用时收集内存。在极端情况下,即使其中一个方法仍在执行,CLR 也可以收集对象!
更新:
这里是一个例子,展示了 GC 将收集对象,即使它们可能仍在范围内。您必须编译发布版本并在调试器之外运行它。
static void Main(string[] args)
{
Console.WriteLine("Before allocation");
var bo = new BigObject();
Console.WriteLine("After allocation");
bo.SomeMethod();
Console.ReadLine();
// The object is technically in-scope here which means it must still be rooted.
}
private class BigObject
{
private byte[] LotsOfMemory = new byte[Int32.MaxValue / 4];
public BigObject()
{
Console.WriteLine("BigObject()");
}
~BigObject()
{
Console.WriteLine("~BigObject()");
}
public void SomeMethod()
{
Console.WriteLine("Begin SomeMethod");
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("End SomeMethod");
}
}
在我的机器上,终结器在 SomeMethod 仍在执行时运行!