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

Posted

技术标签:

【中文标题】.net 中的堆栈和堆内存分配【英文标题】:Stack and Heap memory allocation in .net 【发布时间】:2012-12-05 18:00:29 【问题描述】:

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

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

让我写一个代码sn-p让自己更清楚:

public class Test

    int testInt;
    string testString;


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

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

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

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

using System.Windows.Forms;

namespace WindowsFormsApplication1

    public partial class Form1 : Form
    
        public Form1()
        
            InitializeComponent();
        

        public int anotherInt;
    

我的困惑部分:

在这种情况下,anotherInt 分配到哪里?堆栈还是堆?从表面上看,我认为大多数答案都是“堆栈”。但是,这个变量不是在一个名为Form1 的类中声明的吗?那么,按照上面的第一个代码sn-p,它不应该进入堆吗?如果是,那么在什么情况下将结构分配给堆栈?仅当它在方法内声明时?但是,一个方法难道不属于一个类,它又应该存储在一个堆中吗?

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

【问题讨论】:

我将发布到 Eric Lippert 博客的必填链接:blogs.msdn.com/b/ericlippert/archive/2009/04/27/… 只是想做同样的事情 :) 点赞。 @JonB - 我假设这篇文章指向的答案是“堆”,它只回答了我的一个问题。那么“在什么情况下将结构分配给堆栈?” @Sandeep 您可能不会发现这是一个令人满意的答案(这就是我只发表评论的原因)。这篇文章基本上说一个变量“当它可以”时会进入堆栈。它进一步表示,这对开发人员来说并不重要,而且在技术上根本不需要堆栈。 【参考方案1】:

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

虽然方法属于一个类,但它们是可执行的代码块,而不是与类直接关联的内存块(anotherInt 就是这样)。检查此类分配的最佳方法之一是使用 WinDbg 之类的内存调试器并实际检查您的线程堆栈与堆。这将使您最清楚地了解特定结构的实际分配位置。

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

编辑: 包括blog link.

【讨论】:

【参考方案2】:

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

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

void Foo()

    int localInt = 42;

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

【讨论】:

以上是关于.net 中的堆栈和堆内存分配的主要内容,如果未能解决你的问题,请参考以下文章

堆和堆栈内存是如何管理、实现和分配的?

C++ 中堆栈、静态和堆内存的最大内存

c和c ++中的动态内存分配和堆有啥区别

ava堆栈

关于JS堆栈与拷贝

关于JS堆栈与拷贝