The documentation on PowerShell here has the following interesting comment in it:
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;
Why does powershell
need to be set to null
after being disposed?
It's not directly a PowerShell issue. When a using
block terminates, the specified object(s) have their Dispose()
methods called. These typically do some cleanup operations, often to avoid leaking memory and so forth. However, Dispose()
doesn't delete the object. If a reference to it still exists outside the using
block (as in this example), then the object itself is still in scope. It can't be garbage-collected because there's still a reference to it, so it's still taking up memory.
What they're doing in your example is dropping that reference. When powershell
is set to null, the PowerShell object it was pointing to is orphaned, since there are no other variables referring to it. Once the garbage collector figures that out, it can free up the memory. This would happen at the end of the method anyway (because powershell
would go out of scope), but this way you get the system resources back a little sooner.
(Edit: As Brian Rasmussen points out, the .NET runtime is extremely clever about garbage collection. Once it reaches the last reference to powershell
in your code, the runtime should detect that you don't need it anymore and release it for garbage collection. So the powershell = null;
line isn't actually doing anything.)
By the way, this pattern looks very strange to me. The usual approach is something like this:
using (PowerShell powershell = PowerShell.Create())
{
//...
}
This way, powershell
goes out of scope at the end of the using
block, right after it's disposed. It's easier to tell where the variable is relevant, and you save some code because you don't need the powershell = null
line anymore. I'd even say this is better coding practice, because powershell
never exists in an already-disposed state. If someone modifies your original code and tries to use powershell
outside the using
block, whatever happens will probably be bad.
It doesn't need to be set to null, and it really shouldn't be. The .NET garbage collector is quite capable of detecting that an object not being used after a particular instruction even if your code does not assign a null value to the corresponding variable. (See http://blogs.msdn.com/b/cbrumme/archive/2003/04/19/51365.aspx for details.) As for why an "official" example contains this extra code with misleading comments, even docs can have bugs...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With