- 什么是堆叠和堆叠?
- 他们在电脑记忆中身处何方?
- 它们在多大程度上受到操作系统或语言运行时间的控制?
- 其范围是什么?
- 是什么决定了它们的大小?
- 是什么让一个更快?
当前回答
许多答案作为概念是正确的,但我们必须指出,硬件(即微处理器)需要堆叠,才能调用子程序(集合语言的CALL)。 (OOP的家伙会称之为它)。方法)
在堆叠上,您保存返回地址, 并呼叫 push / ret pop 由硬件直接管理 。
您可以使用堆栈来设定通过参数. 即使比使用登记册要慢( 微处理器大师会说, 还是一本好的 1980s BIOS 书...) 。
- 没有堆叠无 无微处理器可以工作。 (我们无法想象一个程序, 即使是以组装语言, 没有子例程/功能)
- (一个集会语言方案可以工作,因为这个语言方案是一个OS概念,作为cloc,即OS/Lib呼叫。)
堆叠使用速度更快, 如下:
- 硬件,甚至推/棒子都是非常有效的。
- 商场需要进入内核模式,使用锁/气压(或其他同步原始物),执行一些代码,并管理一些跟踪分配情况所需的结构。
其他回答
(我将这一答案从另一个或多或少是这个问题的假象的问题移出。 )
您问题的答案是具体执行问题,可能因汇编者和处理结构而异。但这里是简单的解释。
- 堆叠和堆叠都是从基本操作系统分配的记忆区(通常是虚拟内存,按要求绘制成物理内存)。
- 在一个多轨环境中, 每条线将拥有自己的完全独立的堆叠, 但是它们会共享堆叠 。 同时访问必须控制在堆叠上, 无法在堆叠上 。
堆积物
- 堆积中包含一个链接的旧区块和空空区块列表。
new
或malloc
)通过在自由区块中创建一个合适的区块来满足。这需要更新堆积层上的区块清单。元数据信息堆积物层的区块 也常储存在堆积物层上 在一个小区域 就在每个块块的前面 - 随着堆积增加,新区块往往从下层地址分配到更高的地址。堆肥内存区块的大小随内存分配而增大。如果堆积太小,无法分配,则从基本操作系统获取更多的内存,其内存量往往会增加。
- 分配和分配许多小区块可能会让堆积物离开堆积物的状态下,在用过的区块之间有许许多多的小型自由区块。 分配大区块的请求可能会失败,因为没有一块自由区块能够满足分配要求,即使自由区块的组合体大小可能足够大。 这被称为“无自由区块 ” 。堆积碎裂.
- 当使用过的自由区块旁边的块块在交易时,新的自由区块可以与邻近的自由区块合并,以创建一个更大的自由区块,有效地减少堆积的碎裂。
堆叠
- 堆叠工作通常与一个名为CPU的特别登记簿密切配合进行。堆叠指针。最初,堆叠指针指向堆叠的顶部(堆叠上的最高地址)。
- CPU有特别指示推推堆叠和弹出弹出从堆放堆放的堆放物中推进保存堆叠指针当前位置的值,并减少堆叠指针。 A弹出检索堆叠指针指向的值,然后增加堆叠指针(不要被以下事实混淆):添加堆叠的值减少堆叠指针和删除删除a 值增加数保存并检索的值是 CPU 登记册的值。
- 如果函数有参数,则这些参数在调用到函数之前被推到堆栈上。然后,函数中的代码能够从当前的堆叠指针上导航堆栈以定位这些值。
- 当函数被命名为 CPU 时, 函数会使用特殊指令来按当前指示指示器后,当函数返回时,旧的指令指针会从堆叠中跳下来,然后在调用该函数后,在代码中恢复执行。
- 当输入一个函数时,会降低堆叠指针,以便在堆栈上为本地(自动)变量分配更多空间。如果函数有一个本地32位变量,则在堆栈上留出四个字节。当函数返回时,会将堆叠指针移回所分配的区域。
- 括号函数调用功能像一个护符一样工作。 每一个新调用功能参数、 返回地址和本地变量空间, 以及这些变量激活记录可以堆放嵌套电话,函数返回时会以正确的方式卸载。
- 由于堆叠是一个有限的内存块块, 您可以引起堆叠溢溢溢通过调用过多的嵌套函数和/ 或为本地变量分配过多的空间。 堆栈使用的记忆区域通常设置在堆栈底部( 最低地址) 下方的刻录将触发CPU的陷阱或例外。 此特殊条件随后会被运行时间捕获, 并转换成某种堆叠溢出例外 。
能否在堆叠上而不是堆叠上分配函数 ?
否,函数(即本地变量或自动变量)的激活记录被分配到堆叠上,不仅用于存储这些变量,还用于跟踪嵌套功能电话。
如何管理堆肥实际上要到运行时的环境。 C 使用malloc
C++ 和C++ 用途new
,但许多其他语言都有垃圾收集。
然而,堆叠是一个更低层次的特性,它与处理器结构紧密相连。 当没有足够的空间时堆积起来不会太难, 因为可以在处理堆积的图书馆电话中执行。 但是, 堆叠堆积起来往往是不可能的, 因为堆积溢出的时间太晚才被发现; 关闭行刑线是唯一可行的选择。
堆栈基本上是一个容易获取的内存,仅将它的项目管理为-井-堆叠。事先知道大小的项目可以进入堆叠。数字、字符串、布林亚人的情况就是如此。
缩略堆积是您无法预先确定准确大小和结构的物品的内存。由于天体和阵列可以在运行时变异和变化,它们必须进入堆积。
资料来源:学员人数
堆叠当您调用函数时,该函数的参数加上一些其他间接费用被放在堆栈中。有些信息(例如返回后将到何处)也存储在那里。当您在函数中声明变量时,该变量也分布在堆栈中。
拆分堆栈很简单, 因为您总是按照您分配的反向顺序进行排列。 在输入函数时添加堆叠材料, 当退出时相应数据将被删除。 这意味着您倾向于留在堆叠的小区域内, 除非您调用许多函数来调用其他函数( 或创建循环解决方案 ) 。
堆肥堆积是一个通用的名称, 用于您将创建的数据放在哪里 。 如果您不知道您的程序要创建多少宇宙飞船, 您可能会使用新的( 或商略或等效的) 操作员来创建每艘宇宙飞船 。 此分配将会停留一段时间, 因此我们很可能释放的东西, 与我们创建的顺序不同 。
因此,堆积要复杂得多,因为最终会出现一些未使用的内存区域,这些区域与块状的内存间断 — — 内存会变得支离破碎。 找到您需要的大小的自由内存是一个困难的问题。 这就是为什么应该避免堆积(尽管它仍然经常被使用 ) 。
执行 执行 执行堆叠和堆叠的操作通常要到运行时间/操作系统。 通常游戏和其他功能至关重要的应用程序会创造自己的内存解决方案,从堆叠中抓取大量内存,然后在内部将内存分离出来,以避免依赖操作系统进行内存。
只有当你的记忆用法与常规有很大不同时, 也就是在游戏中, 在一个巨大的操作中加载一个水平, 并且可以在另一个巨大的操作中将整个批量扔掉时, 这才是实际的。
内存物理位置这比你想的要少 因为一种技术叫做虚拟内存这使得您的程序认为您可以访问某位地址, 物理数据在其他地方( 甚至是硬盘上! ) 。 您获得的堆叠地址随着您的呼叫树越深, 顺序越大。 堆放的地址是不可预知的( 具体化) , 坦率地说并不重要 。
OK,OK, OK, OK, OK, OK, OK, OK, OK,OK, OK,OK,OK,OK,OK,OK,OK,OK,OK,OK,OK,OK,OK,OK,OK,OK,OK,OK,OK,OK,OK,OK,OK,OK,OK,OK,OK,OK,OK,OK,OK,OK,OK,OK,简言简简短地说,它们的意思是:已订购和未排序...!
堆堆叠:在堆叠的物品中,事情会相互占据顶端, 意味着处理的速度会更快,效率会更高!
所以总是有一个索引来指向特定项目, 处理速度也会更快, 这些项目之间也有关系!
堆肥:没有订单,处理速度会放慢, 价值会混乱在一起,没有具体的订单或索引... ......有随机的,它们之间没有关系... 所以执行和使用时间可以不同...
我还创造了下面的图像,以显示他们可能长得如何:
我想许多其他人 已经给了你 大多是正确的答案 这个问题。
然而,一个被忽略的细节是,“堆积”实际上可能应该被称为“免费商店 ” 。 之所以有这种区别,是因为最初的免费商店是用一个称为“binomial heap”的数据结构实施的。 因此,从早期实施中分配的麦洛克()/免费()是从堆积中分配的。 然而,在现代,大部分免费商店都是用非常精密的数据结构实施的,而不是二元式的堆积。