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

最近,我读到了关于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);
}
现在,程序报告“像素为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. 
    }