最近,我读了Jon Skeet's Blog谈论C#对象的占用空间和开销。我写了下面的代码来复制他的实验。结构/值类型内存分配和解除位置
class Pixel
{
private byte _r;
private byte _g;
private byte _b;
public int x { get; set; }
public int y { get; set; }
public System.Windows.Media.Color Color
{
get { return System.Windows.Media.Color.FromRgb(_r, _g, _b); }
}
}
static void Main(string[] args)
{
size = 1000;
var array3 = new Pixelsize];
before = GC.GetTotalMemory(true);
for (int i = 0; i < size; i++)
{
array3[i] = new Pixel();
}
after = GC.GetTotalMemory(true);
Console.WriteLine("Pixel is {0} bytes", (after - before)/size);
}
到目前为止好,该程序报告"Pixel is 15 bytes"
,这是8个字节基地+ 4个字节+ 1 + 1 + 1 = 15个字节。
然后我想知道:struct
实例是否具有与class
实例相同的开销。所以我将Pixel
更改为struct
。
struct Pixel
{
private byte _r;
private byte _g;
private byte _b;
public int x { get; set; }
public int y { get; set; }
public System.Windows.Media.Color Color
{
get { return System.Windows.Media.Color.FromRgb(_r, _g, _b); }
}
}
现在,程序报告"Pixel is 0 bytes"
。进入代码,我发现after
与before
相同。所以struct是一个值类型,它是从堆栈中分配的。对?除此之外,当我检查寄存器“ESP
”根本没有改变。所以它不是从堆栈中分配的?
查看TaskManager,演示程序的内存使用量在分配后增加了8000个字节。这8000字节来自哪里?
最后,由于GC未取消内存分配,我该如何取消分配此内存?我试图将分配代码放在一个块内,并希望array3超出范围时,这些内存将被释放。但是,内存使用情况没有改变。我在这里得到内存泄漏吗?
static void Main(string[] args)
{
{
size = 1000;
var array3 = new Pixelsize];
before = GC.GetTotalMemory(true);
for (int i = 0; i < size; i++)
{
array3[i] = new Pixel();
}
after = GC.GetTotalMemory(true);
Console.WriteLine("Pixel is {0} bytes", (after - before)/size);
}
//Expect the memory to be released here, but nothing happened.
}
这意味着什么? – 2014-10-07 03:40:19