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

我一直在阅读关于这个主题的不同文章/页面,最后来到这篇文章,这导致了我的困惑!

在文章中提到, Value Types always go where they were declared ,作者的意思是,值类型可以驻留在堆栈或堆中,就像它们声明的方式/位置一样。

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

public class Test
{
    int testInt;
    string testString;
}

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

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

在这里输入图像描述

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的类中声明的? 所以,按照上面的第一个代码片段,它不应该堆到堆上吗? 如果是,那么在什么情况下将结构分配给堆栈? 只有在方法中声明它时? 但是,仍然不会有一种方法归类到一个类中,而这个方法又应该存储在一个堆中?

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


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

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

在一个非常简化的意义上:Stack =当前正在执行的代码堆栈所需的地址,Heap =其他所有内容。 但最终,Jon B与他的博客链接。 你真的不需要知道你的对象分配在哪里。

编辑:包括博客链接。


在你的例子中, anotherInt将与Form1的其他实例一起位于堆上(假设你创建了一个实例)。

要创建一个本地int,变量必须在方法或属性中声明。 例如

void Foo()
{
    int localInt = 42;
}

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

链接地址: http://www.djcxy.com/p/80447.html

上一篇: Stack and Heap memory allocation in .net

下一篇: How does the operating system detect a stack overflow?