これは直接 PowerShell の問題ではありません。using
ブロックが終了すると、指定されたオブジェクトのメソッドDispose()
が呼び出されます。これらは通常、メモリリークなどを避けるために、いくつかのクリーンアップ操作を行います。ただし、Dispose()
オブジェクトは削除しません。オブジェクトへの参照がまだブロックの外に存在する場合using
(この例のように)、オブジェクト自体はまだスコープ内にあります。それへの参照がまだあるため、ガベージ コレクションを行うことはできません。したがって、まだメモリを占有しています。
あなたの例で彼らがしているのは、その参照を削除することです。が null に設定されている場合powershell
、参照している他の変数がないため、それが指していた PowerShell オブジェクトは孤立しています。ガベージ コレクターがそれを把握すると、メモリを解放できます。いずれにせよ、これはメソッドの最後に発生します (powershell
範囲外になるため) が、この方法では、システム リソースを少し早く元に戻すことができます。
(編集: Brian Rasmussen が指摘しているように、.NET ランタイムはガベージ コレクションに関して非常に巧妙です。powershell
コード内の最後の参照に到達すると、ランタイムはそれがもう必要ないことを検出し、ガベージ コレクションのために解放する必要があります。したがって、このpowershell = null;
行は実際には何もしていません。)
ところで、このパターンは私には非常に奇妙に見えます。通常のアプローチは次のようなものです。
using (PowerShell powershell = PowerShell.Create())
{
//...
}
このようにして、ブロックが破棄された直後powershell
のブロックの最後で範囲外になります。変数がどこに関連しているかが分かりやすくなり、行using
が不要になるためコードを節約できます。すでに処分された状態には決して存在しないpowershell = null
ため、これはより良いコーディング方法であるとさえ言えます。powershell
誰かがあなたの元のコードを変更しpowershell
、ブロックの外で使用しようとするとusing
、何が起こってもおそらく悪いことになります.