今日、List<参照型>にデータを追加して、GCを強制的に発生させた時に、GCを一度コールしただけでは、ガーベジコレクション対象のオブジェクトが破棄されないという現象がありました。(GC.GetTotalMemoryの値が0でない)
以下にサンプルを示します。非常に不思議なのが、stringも参照型なのに、List<string>は正常に動作するのに、独自で作成したクラスの場合には破棄されません。GCのところはサンプルのようにするとGC.GetTotalMemoryの値が0になります。
最初に、GCが別スレッドになっていて、遅延発生かなとおもい、しばらく待っていてもだめでした。
internal class 参照
{
public 参照(int 値)
{
m_数値[0] = 値.ToString();
}
~参照()
{
}
private string[] m_数値 = new string[1000];
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private const int カウント = 100000;
private void button1_Click(object sender, EventArgs e)
{
List<string> List = new List<string>();
for (int i = 0; i < カウント; i++)
List.Add(i.ToString());
}
private void button2_Click(object sender, EventArgs e)
{
List<参照> List = new List<参照>();
for (int i = 0; i < カウント; i++)
List.Add(new 参照(i));
}
private void button3_Click(object sender, EventArgs e)
{
long メモリ = GC.GetTotalMemory(false) / 1024 / 1024;
MessageBox.Show(メモリ.ToString());
GC.Collect();
Thread.Sleep(1000);
GC.Collect();
メモリ = GC.GetTotalMemory(false) / 1024 / 1024;
MessageBox.Show(メモリ.ToString());
}
}
以下にサンプルを示します。非常に不思議なのが、stringも参照型なのに、List<string>は正常に動作するのに、独自で作成したクラスの場合には破棄されません。GCのところはサンプルのようにするとGC.GetTotalMemoryの値が0になります。
最初に、GCが別スレッドになっていて、遅延発生かなとおもい、しばらく待っていてもだめでした。
internal class 参照
{
public 参照(int 値)
{
m_数値[0] = 値.ToString();
}
~参照()
{
}
private string[] m_数値 = new string[1000];
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private const int カウント = 100000;
private void button1_Click(object sender, EventArgs e)
{
List<string> List = new List<string>();
for (int i = 0; i < カウント; i++)
List.Add(i.ToString());
}
private void button2_Click(object sender, EventArgs e)
{
List<参照> List = new List<参照>();
for (int i = 0; i < カウント; i++)
List.Add(new 参照(i));
}
private void button3_Click(object sender, EventArgs e)
{
long メモリ = GC.GetTotalMemory(false) / 1024 / 1024;
MessageBox.Show(メモリ.ToString());
GC.Collect();
Thread.Sleep(1000);
GC.Collect();
メモリ = GC.GetTotalMemory(false) / 1024 / 1024;
MessageBox.Show(メモリ.ToString());
}
}
※コメント投稿者のブログIDはブログ作成者のみに通知されます