C# 结构/值类型内存分配和解除锁定
最近,我读到了关于C#对象占用空间和开销的讨论。我编写了以下代码来复制他的实验C# 结构/值类型内存分配和解除锁定,c#,memory,memory-management,C#,Memory,Memory Management,最近,我读到了关于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
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);
}
现在,程序报告“像素为0字节”。进入代码,我发现之后的与之前的相同。所以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.
}
static void Main(字符串[]args)
{
{
尺寸=1000;
var array3=新像素大小];
before=GC.GetTotalMemory(true);
对于(int i=0;i
在函数内分配引用类型的数组时。。对阵列本身的引用可以存储在预先分配的堆栈帧上(即,对于32/64位,4/8字节)。1000个元素的实际分配在堆上,同样是每个元素4/8字节。此外,类的实例在调用new Pixel()
时分配,并保持活动状态,因为它们的引用存储在数组中
将其更改为值类型的数组时,在函数内。。对阵列本身的引用可以存储在预先分配的堆栈帧上(即,对于32/64位,4/8字节)。1000个元素的实际分配在堆上,每个元素的大小为x字节,其中x是值类型的大小。分配给数组元素的任何值都会被复制,每个字节数组元素未引用任何内容。
由于分配了值类型数组,因此在调用before=GC.GetTotalMemory(true)之前代码>,之前和之后在分配中看不到任何差异
换句话说,对于类,分配在第array3[i]=new Pixel()行代码>(在堆上)
但在sruct的情况下,分配在第var array3行=新像素[大小]代码>
对于结构,newpixel()
在堆栈上使用一点空间,但随后将该值复制到堆中为数组预先分配的空间中。。。并且很可能在每次迭代中重用堆栈空间
如果您考虑的是int
数组而不是Pixel
数组,那么考虑整个问题可能会更容易。。除了大小不同之外,int
和Pixel
(定义为struct)之间的机制是相同的
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.
}