如何在循环中分配内存?

问题描述 投票:0回答:1

我想为Foo创建10个实例

class Program
{
    static void Main(string[] args) {

        foreach (var _ in Enumerable.Range(1, 10)) 
        {
            var foo = new Foo();
        }

        Console.ReadKey();

    }
}

但我用VS2019的诊断工具跟踪堆内存,它只显示1个计数。

为什么Foo类型没有10个计数?在堆中应该有10个Foo的实例内存,但只有一个点到'foo'栈。请给我一些建议,谢谢。

@TaW : 我参考了你的建议,我在循环外创建了10个实例,但诊断工具仍然只在托管堆中显示一个计数。

static void Main(string[] args)
    {
        Foo foo;
        foo = new Foo();
        foo = new Foo();
        foo = new Foo();
        foo = new Foo();
        foo = new Foo();
        foo = new Foo();
        foo = new Foo();
        foo = new Foo();
        foo = new Foo();
        foo = new Foo();


        Console.ReadKey();

    }

但是诊断工具仍然只显示一个计数在托管堆中。

enter image description here

-----------------------------------另一个发现

我尝试循环100K次来创建Foo实例,并在Foo类型中添加了一个分配1024大小的字节[]。

static void Main(string[] args)
    {

        foreach (var _ in Enumerable.Range(0, 100000))  {

            var foo = new Foo();

        }

        Console.ReadKey();

    }

class Foo
{
    private byte[] bytes;
    public Foo()
    {
        bytes = new byte[1024];
    }

}

诊断工具仍然在托管堆中显示一个计数,并且没有检测到进程内存中的任何GC。这似乎是行不通的。enter image description here

我试着用.Net对象分配跟踪来解决这个问题。Debug -> Performance Profiler -&gt。.Net Object Allocation Tracking 来监测它。

报告中预计有10万次分配和触发GC。

enter image description here

enter image description here

现在,我更困惑的是两者之间的突出区别。diagnostic tool.Net Object Allocation Tracking.

c# .net memory-management
1个回答
1
投票
  1. 每当GC觉得喜欢的时候,坦率地说,变量永远不会被读取,所以它永远是合格的。
  2. foo 是变量--它在栈中对引用有一个固定的位置;然而,每个 new Foo() 是一个不同的对象,在可用的堆空间中的某个地方创建;每次都不同。
  3. 严格来说,变量的实际声明点(在IL中)和while的实际实现方式有一些复杂之处--但这只有在退出循环后才会显现出来。而且由于在每次迭代时你都会立即分配它,所以这里并没有明显的区别
© www.soinside.com 2019 - 2024. All rights reserved.