- 1. 概要
- 2. 明示的に破棄
- 3. Using の使用
1. 概要
「C#」には、ガベージコレクションちゅうものがありまして。
これを持っておる言語は、メモリに関して、明示的に確保したり解放したりしなくても、勝手に確保してくれるし、使わなくなったメモリは、勝手に開放してくれることになっているのですが。
なかなか、思いどおりにならない。
メモリの確保に関しては、ほとんど問題になることはないのですが、解放に関しては、思いどおりにならないことが多い。
明示的に解放しないと、いつまでたってもメモリを使いっぱなしになることが多々あるのです。
本ページは、下記のサイトを参考にさせていただきました。
「オブジェクトの破棄(C#)」
2. 明示的に破棄
オブジェクトの使用が終わった時点で、オブジェクトに対して、「null」を設定することにより、明示的に使用が終了したことを知らせることができるそうです。
using System;
using System.Linq;
public class Program
{
static public void Main ()
{
int[] arr1 = new int[10000];
for (int i=0; i<arr1.Length; i++)
{
arr1[i] = i;
}
GC.Collect();
Console.WriteLine("使用ヒープサイズ["+ GC.GetTotalMemory(true).ToString("#,0") +"]");
int[] arr2 = arr1;
GC.Collect();
Console.WriteLine("使用ヒープサイズ["+ GC.GetTotalMemory(true).ToString("#,0") +"]");
arr1 = null;
GC.Collect();
Console.WriteLine("arr2 末尾["+ arr2.Last() +"]");
Console.WriteLine("使用ヒープサイズ["+ GC.GetTotalMemory(true).ToString("#,0") +"]");
arr2 = null;
GC.Collect();
Console.WriteLine("使用ヒープサイズ["+ GC.GetTotalMemory(true).ToString("#,0") +"]");
}
}
てなソースを書いて、ビルド・実行すると、下記の結果が得られます。
使用ヒープサイズ[4,251,472]
使用ヒープサイズ[4,293,384]
arr2 末尾[9999]
使用ヒープサイズ[4,286,720]
使用ヒープサイズ[4,260,952]
ヒープサイズは、その時々によって、異なるので、これは、実行するたびに値が変わったりしますが。
「null」を設定することにより、ある程度、メモリが解放されることがわかります。
3. Using の使用
これ、うまく説明できないのです。
参考サイトによれば、「System.IO.FileStream」のようなクラスは、「IDisposable」を継承しているのだそうで。
「IDisposable」クラスを継承しているものは、「Dispose」メソッドを持っているらしいのです。
で、こういう「IDisposable」クラスを継承して、「Dispose」メソッドを持っているものは、「Using」が使えるのですと。
using System;
using System.IO;
public class filestream
{
static public void Main ()
{
using (FileStream fs = new FileStream(@"./Hello.txt", FileMode.Append, FileAccess.Write, FileShare.Write))
{
using (StreamWriter w = new StreamWriter(fs))
{
w.WriteLine(@"Hello FileStream");
}
}
}
}
のように、「Using」以下にあるものは、明示的に書いていなくても「Using」から抜けるときに、「Dispose」が呼ばれるそうで、書かないでいても「Close」し、オブジェクトを破棄し、やリソースを解放してくれるそうです。
また、例外が発生する場合も、明示的に書いていなくても、「Using」の外に出る前に、「finally」が自動的に実行されてそこで「Dispose」が動作するそうな。
ということは、「Using」が使えるものは、特に他の理由がない限りは、「Using」を使うべきですな。
|