PowerShell here上的文档中包含以下有趣的评论:
PowerShell powershell = PowerShell.Create();
using (powershell)
{
//...
}
// Even after disposing of the PowerShell object, we still
// need to set the powershell variable to null so that the
// garbage collector can clean it up.
powershell = null;
为什么powershell
被处置后需要设置为null
?
答案 0 :(得分:16)
这不是直接的PowerShell问题。当using
块终止时,指定的对象调用其Dispose()
方法。这些通常会执行一些清理操作,通常是为了避免泄漏内存等等。但是,Dispose()
不会删除该对象。如果对它的引用仍然存在于using
块之外(如本示例所示),则对象本身仍在范围内。它不能被垃圾收集,因为它仍然有一个引用它,所以它仍然占用内存。
他们在你的例子中正在做的是删除该引用。当powershell
设置为null时,它指向的PowerShell对象是孤立的,因为没有其他变量引用它。一旦垃圾收集器发现它,就可以释放内存。无论如何,这将发生在方法的最后(因为powershell
将超出范围),但这样可以更快地恢复系统资源。
(编辑:正如Brian Rasmussen指出的那样,.NET运行时对垃圾收集非常聪明。一旦它到达代码中对powershell
的最后一个引用,运行时应该检测到你不再需要它并释放它以进行垃圾收集。所以powershell = null;
行实际上并没有做任何事情。)
顺便说一句,这个模式对我来说很奇怪。通常的做法是这样的:
using (PowerShell powershell = PowerShell.Create())
{
//...
}
这样,powershell
块在using
块的末尾超出范围,就在它被处置之后。更容易分辨变量的相关位置,并保存一些代码,因为您不再需要powershell = null
行。我甚至说这是更好的编码实践,因为powershell
永远不会存在于已处置状态。如果有人修改了您的原始代码并尝试在powershell
块之外使用using
,则无论发生什么都可能不好。
答案 1 :(得分:7)
它不需要设置为null,它确实不应该。即使您的代码没有为相应的变量赋值空值,.NET垃圾收集器也能够检测到特定指令后未使用的对象。 (有关详细信息,请参阅http://blogs.msdn.com/b/cbrumme/archive/2003/04/19/51365.aspx。)至于为什么“官方”示例包含带有误导性评论的额外代码,甚至文档也可能存在错误...
答案 2 :(得分:1)
建议不正确,只要它无法访问它就有资格进行垃圾回收。 (请参阅What is the correct way to free memory in C#了解一些代码的代码)
你真的只在对象Dispose
方法