.net中的堆栈和堆内存分配

时间:2012-12-18 13:54:25

标签: .net heap-memory value-type reference-type stack-memory

我一直在阅读关于这个主题的不同文章/页面,最后来到this article,这让我感到困惑!

在文章中,提到作者所指的Value Types always go where they were declared,值类型可以驻留在堆栈或堆中,根据它们声明的方式/位置。

让我放下一段代码片段,让自己更清楚:

public class Test
{
    int testInt;
    string testString;
}

int anInt;
string aString;
Test testObj;
testObj = new Test();

执行这些代码行后,内存分配将如下所示:

enter image description here

struct testInt存储在堆中,因为它是在Test类中声明的。

记住这个例子,让我们看一下我声明一个整数的简单Form.cs代码。

using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public int anotherInt;
    }
}

我的困惑部分:

在这种情况下,anotherInt分配给哪里?堆栈还是堆?从它的外观来看,我认为大多数答案都是“Stack”。但是,这个变量不是在名为Form1的类中声明的吗?那么,根据上面的第一个代码片段,它不应该进入堆?如果是,那么在什么情况下将结构分配给堆栈?只有在方法中声明它?但是,仍然不会将一个方法放在一个类中,它又应该存储在一个堆中吗?

我知道很多问题!但只是想知道发生了什么。我希望我的问题很明确。

2 个答案:

答案 0 :(得分:2)

在您的示例中,anotherInt将分配给堆。这是因为anotherIntForm1的字段,它是堆分配的对象。堆栈与线程相关联。仅包含当前执行代码所需的引用/对象。所以要回答你关于课堂下方法的问题,那你就不那么正确了。

虽然方法属于一个类,但它们是可执行的代码块,而不是直接与类关联的内存块(anotherInt是)。检查此类分配的最佳方法之一是使用内存调试程序,如WinDbg&实际上检查你的线程堆栈与堆。这将为您提供实际分配特定结构的位置的最清晰图像。

在极其简化的意义上:Stack =当前执行代码堆栈所需的地址,Heap =其他所有内容。但是,ultimatley Jon B是他与Eric博客的链接。你真的不需要知道对象的分配位置。

编辑: 包括blog link.

答案 1 :(得分:2)

在您的示例中,anotherInt将与Form1实例的其余部分一起位于堆上(假设您创建了一个当然)。

要创建局部int,必须在方法或属性中声明变量。例如。

void Foo()
{
    int localInt = 42;
}

现在,仅仅因为在方法中声明值类型并不一定意味着它进入堆栈。例如。捕获的变量处理方式不同。