• 什么是堆叠和堆叠?
  • 他们在电脑记忆中身处何方?
  • 它们在多大程度上受到操作系统或语言运行时间的控制?
  • 其范围是什么?
  • 是什么决定了它们的大小?
  • 是什么让一个更快?

当前回答

其他人对大中风的反应也很好, 所以我要讲一些细节。

  1. 堆放和堆放不需要是单数的 。 堆放和堆放的多处常见情况是, 您在一个过程中拥有多个线条。 在此情况下, 每个线条都有自己的堆放。 您也可以有多个堆放。 例如, 某些 DLL 配置可能导致不同堆放的 DLL 分配不同的 DLL , 这就是为什么释放不同图书馆分配的内存通常是一个坏主意 。

  2. 在 C 中,您可以通过使用单花,它分配在堆叠上,而不是 Alloc,它分配在堆肥上。这个记忆不会保存在您的返回语句中,但它对刮痕缓冲很有用。

  3. 在 Windows 上做一个不使用很多内容的大型临时缓冲区不是免费的。 这是因为编译器将生成一个堆叠探测器循环, 每次输入您的函数时都会被调用, 以确保堆叠存在( 因为 Windows在堆叠的末尾使用一个单个的守护页面来检测堆叠的生长需要。 如果您访问堆叠尾端的多页内存, 您将会崩溃 ) 。 例如 :

void myfunction()
{
   char big[10000000];
   // Do something that only uses for first 1K of big 99% of the time.
}

其他回答

几分钱:我想,画出内存图形和简单一些是件好事:

This is my vision of process memory construction with simplification for more easy understanding wht happening


箭头 - 显示生长堆叠和堆叠、流程堆叠大小的极限, 以 OS 定义, 通常由线条中的线状堆叠大小的参数来设定 API 。 厚通常通过进程限制最大虚拟内存大小, 例如32 位 2 - 4 GB 。

简单的方法就是简单的方法:过程堆叠对于过程和内部所有线条都是一般的, 用于记忆分配, 通常使用类似的方式中偏().

Stack 是常见情况下存储的快速内存, 用于存储函数返回指针和变量, 处理为函数调用参数, 本地函数变量 。

其他人对大中风的反应也很好, 所以我要讲一些细节。

  1. 堆放和堆放不需要是单数的 。 堆放和堆放的多处常见情况是, 您在一个过程中拥有多个线条。 在此情况下, 每个线条都有自己的堆放。 您也可以有多个堆放。 例如, 某些 DLL 配置可能导致不同堆放的 DLL 分配不同的 DLL , 这就是为什么释放不同图书馆分配的内存通常是一个坏主意 。

  2. 在 C 中,您可以通过使用单花,它分配在堆叠上,而不是 Alloc,它分配在堆肥上。这个记忆不会保存在您的返回语句中,但它对刮痕缓冲很有用。

  3. 在 Windows 上做一个不使用很多内容的大型临时缓冲区不是免费的。 这是因为编译器将生成一个堆叠探测器循环, 每次输入您的函数时都会被调用, 以确保堆叠存在( 因为 Windows在堆叠的末尾使用一个单个的守护页面来检测堆叠的生长需要。 如果您访问堆叠尾端的多页内存, 您将会崩溃 ) 。 例如 :

void myfunction()
{
   char big[10000000];
   // Do something that only uses for first 1K of big 99% of the time.
}

(我将这一答案从另一个或多或少是这个问题的假象的问题移出。 )

您问题的答案是具体执行问题,可能因汇编者和处理结构而异。但这里是简单的解释。

  • 堆叠和堆叠都是从基本操作系统分配的记忆区(通常是虚拟内存,按要求绘制成物理内存)。
  • 在一个多轨环境中, 每条线将拥有自己的完全独立的堆叠, 但是它们会共享堆叠 。 同时访问必须控制在堆叠上, 无法在堆叠上 。

堆积物

  • 堆积中包含一个链接的旧区块和空空区块列表。newmalloc)通过在自由区块中创建一个合适的区块来满足。这需要更新堆积层上的区块清单。元数据信息堆积物层的区块 也常储存在堆积物层上 在一个小区域 就在每个块块的前面
  • 随着堆积增加,新区块往往从下层地址分配到更高的地址。堆肥内存区块的大小随内存分配而增大。如果堆积太小,无法分配,则从基本操作系统获取更多的内存,其内存量往往会增加。
  • 分配和分配许多小区块可能会让堆积物离开堆积物的状态下,在用过的区块之间有许许多多的小型自由区块。 分配大区块的请求可能会失败,因为没有一块自由区块能够满足分配要求,即使自由区块的组合体大小可能足够大。 这被称为“无自由区块 ” 。堆积碎裂.
  • 当使用过的自由区块旁边的块块在交易时,新的自由区块可以与邻近的自由区块合并,以创建一个更大的自由区块,有效地减少堆积的碎裂。

The heap

堆叠

  • 堆叠工作通常与一个名为CPU的特别登记簿密切配合进行。堆叠指针。最初,堆叠指针指向堆叠的顶部(堆叠上的最高地址)。
  • CPU有特别指示推推堆叠和弹出弹出从堆放堆放的堆放物中推进保存堆叠指针当前位置的值,并减少堆叠指针。 A弹出检索堆叠指针指向的值,然后增加堆叠指针(不要被以下事实混淆):添加堆叠的值减少堆叠指针和删除删除a 值增加数保存并检索的值是 CPU 登记册的值。
  • 如果函数有参数,则这些参数在调用到函数之前被推到堆栈上。然后,函数中的代码能够从当前的堆叠指针上导航堆栈以定位这些值。
  • 当函数被命名为 CPU 时, 函数会使用特殊指令来按当前指示指示器后,当函数返回时,旧的指令指针会从堆叠中跳下来,然后在调用该函数后,在代码中恢复执行。
  • 当输入一个函数时,会降低堆叠指针,以便在堆栈上为本地(自动)变量分配更多空间。如果函数有一个本地32位变量,则在堆栈上留出四个字节。当函数返回时,会将堆叠指针移回所分配的区域。
  • 括号函数调用功能像一个护符一样工作。 每一个新调用功能参数、 返回地址和本地变量空间, 以及这些变量激活记录可以堆放嵌套电话,函数返回时会以正确的方式卸载。
  • 由于堆叠是一个有限的内存块块, 您可以引起堆叠溢溢溢通过调用过多的嵌套函数和/ 或为本地变量分配过多的空间。 堆栈使用的记忆区域通常设置在堆栈底部( 最低地址) 下方的刻录将触发CPU的陷阱或例外。 此特殊条件随后会被运行时间捕获, 并转换成某种堆叠溢出例外 。

The stack

能否在堆叠上而不是堆叠上分配函数 ?

否,函数(即本地变量或自动变量)的激活记录被分配到堆叠上,不仅用于存储这些变量,还用于跟踪嵌套功能电话。

如何管理堆肥实际上要到运行时的环境。 C 使用mallocC++ 和C++ 用途new,但许多其他语言都有垃圾收集。

然而,堆叠是一个更低层次的特性,它与处理器结构紧密相连。 当没有足够的空间时堆积起来不会太难, 因为可以在处理堆积的图书馆电话中执行。 但是, 堆叠堆积起来往往是不可能的, 因为堆积溢出的时间太晚才被发现; 关闭行刑线是唯一可行的选择。

堆叠是记忆的一部分, 可以通过若干关键组装语言指令来操作, 如“ pop”( 移动并返回堆放中的值) 和“ push” (将值推到堆放中) , 但也可以调用( 调用子例程 - 将地址推回堆放中) 和调用( 从子例程返回 - 将堆放中的地址从堆放中跳出, 跳到堆放中) 。 这是堆叠指针登记册下的内存区域, 可根据需要设置 。 堆叠还用于将参数通过子例程, 并在调用子例程前保存登记册中的值 。

堆积是操作系统向一个应用程序提供的内存的一部分,通常通过像麦洛克这样的轮号。 在现代操作系统上,这个内存是一组只有呼叫程序才能进入的页面。

堆叠的大小在运行时确定, 通常在程序启动后不会增长。 在 C 程序中, 堆叠需要足够大, 以保持每个函数中所有声明的变量。 堆叠会根据需要动态增长, 但操作系统最终会发出呼唤( 它会增加的堆积量往往超过 merloc 所要求的值, 这样至少有些未来的中枢不需要返回内核以获取更多的内核内存。 这种行为通常可以自定义 )

因为您在启动程序前已经分配了堆叠, 所以在您使用堆叠之前, 您从不需要使用堆叠, 所以这有点优势。 实际上, 很难预测什么是快速的, 在拥有虚拟内存子系统的现代操作系统中什么是缓慢的, 因为这些页面是如何执行的, 在哪里存储的, 是一个执行细节 。

在下面的 C# 代码中

public void Method1()
{
    int i = 4;
    int y = 2;
    class1 cls1 = new class1();
}

下面是内存管理的方法

Picture of variables on the stack

Local Variables只需在堆叠中进行函数调用, 就会持续多久。 堆放堆放的堆放量用于那些我们一生中并不真正了解的变量, 但是我们期望它们会持续一段时间。 在大多数语言中, 关键是我们在编译时知道一个变量有多大, 如果我们想将其存储在堆放堆放中, 就必须知道它有多大 。

对象( 大小随更新而不同 ) 跳到堆积上, 因为我们不知道在创建时它们会持续多久 。 在许多语言中, 堆积是垃圾, 以寻找不再有任何引用的对象( 如 cls1 对象 ) 。

在 Java 中, 大多数对象都直接进入堆肥中。 在 C / C++ 等语言中, 支架和类通常可以在不与指针打交道时留在堆叠中 。

更多信息,请访问以下网站:

Timmurphy. org 表示堆叠和堆积记忆分配的差别。

此处 :

在堆叠和堆放上创建对象

本条是上述情况的来源:6个重要的.NET概念:堆叠、堆积、价值类型、参考类型、拳击和拆箱-代码项目

但要知道它可能含有一些不准确之处。