class MyControl : Control
{
}
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i < 100; i++)
{
using (MyControl c = new MyControl())
{
}
}
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
Console.Write("!");
}
Пробуем смотреть что в памяти:
.load sos.dll
extension C:\Windows\Microsoft.NET\Framework\v2.0.50727\sos.dll loaded
!dumpheap -stat -type MyControl
PDB symbol for mscorwks.dll not loaded
total 1 objects
Statistics:
MT Count TotalSize Class Name
001372ac 1 104 TestMemLeak.Form1+MyControl
Total 1 objects
Здравствуйте, маген, Вы писали:
М>Не пойму, почему один контрол в памяти остается?
В какой момент смотрим?
Если после цикла, то вполне возможно, что это тот экземпляр, который находится в переменной "c". Она хоть и не видна вне using-блока в C#, но в IL все переменные декларируются перед телом метода, посему объект может быть жив после выхода из блока.
Здравствуйте, hardcase, Вы писали:
H>Здравствуйте, маген, Вы писали:
М>>Не пойму, почему один контрол в памяти остается?
H>В какой момент смотрим? H>Если после цикла, то вполне возможно, что это тот экземпляр, который находится в переменной "c". Она хоть и не видна вне using-блока в C#, но в IL все переменные декларируются перед телом метода, посему объект может быть жив после выхода из блока.
Смотрел в момент выхода из процедуры, где Console.Write.
Ну и после выхода из процедуры через некоторое время — делал паузу и смотрел.
Проблема воспроизводится когда объекты наследуем от типа Control.
В том числе если берем не MyControl, а Label, TextBox и т.д.
Если взять за базовый скажем object, проблема не воспроизводится.
Здравствуйте, _FRED_, Вы писали:
_FR>Здравствуйте, маген, Вы писали:
М>>Пробуем смотреть что в памяти:
_FR>Смотрите на код, скомпилированный со включёнными оптимизациями (Release) или без оных (Debug)?
Здравствуйте, hardcase, Вы писали:
H>Здравствуйте, маген, Вы писали:
М>>Не пойму, почему один контрол в памяти остается?
H>В какой момент смотрим? H>Если после цикла, то вполне возможно, что это тот экземпляр, который находится в переменной "c". Она хоть и не видна вне using-блока в C#, но в IL все переменные декларируются перед телом метода, посему объект может быть жив после выхода из блока.
Похоже Вы правы!
Если написать так, то проблема пропадает.
Control c = new MyControl();
c.Dispose();
c = null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
Здравствуйте, маген, Вы писали:
М>>>Пробуем смотреть что в памяти: _FR>>Смотрите на код, скомпилированный со включёнными оптимизациями (Release) или без оных (Debug)? М>Debug.
И совершенно напрасно. Профилировать (измерять производительность или потребление ресурсов) debug-сборок, в большинстве случаев, несколько бессмысленно.
Help will always be given at Hogwarts to those who ask for it.