堆叠和堆肥是什么?它们实际上位于计算机的内存中在哪里?它们在多大程度上被操作时间或语言控制?它们的范围是什么?它们的大小是什么?它们大小是什么?一个的大小是什么使一个更快?
当前回答
堆栈是内存的一部分,可以通过若干关键组装语言指令来操作,例如“pop”(从堆叠中移动并返回一个值)和“push”(将一个值推到堆叠中),但也可以调用(调用子例程 - 将地址推到堆叠中)和返回( 从子例程返回 - 将堆叠的地址从堆叠中跳出并跳到堆叠中)。这是堆叠指针登记册下方的内存区域,可以根据需要设置。堆叠也用于 pa 。
堆积是操作系统向一个应用程序提供的内存的一部分, 通常通过像马洛克这样的音响。 在现代套管上, 这个内存是一组只有呼叫程序才能进入的页面 。
堆叠的大小在运行时确定, 一般在程序启动后不会增长。 在 c 程序中, 堆叠需要足够大, 以保持每个函数中所有声明的变量。 堆叠会按需要动态增长, 但 巨头最终会发出呼唤( 它会增加的堆积量通常超过 merloc 要求的值, 这样至少有些未来的中枢不需要返回内核来获取更多的内核内存 。 此行为通常可以自定义 )
因为您在启动程序前已经分配了堆叠, 所以在您使用堆叠之前, 您从不需要在使用堆叠前使用滚动, 所以在实际操作中这是一个小的优势。 实际上, 很难预测什么是快速的,什么是缓慢的, 在拥有虚拟内存子系统的现代操作系统中, 因为这些页面是如何被安装的, 在哪里存储的, 是一个执行细节 。
其他回答
因为有些答案没有被选中, 我要贡献我的米特。
令人惊讶的是,没有人提到,不仅在外来语言(文稿)或平台(英特环)中,而且在纤维、绿线和一些共程实施中,都能找到多个(即与运行的骨层线数无关的)呼叫堆叠。
纤维、绿线和绿线在很多方面都相似,这导致许多混乱。 纤维和绿线之间的区别在于前者使用合作性多任务,而后者可能以合作性或先发制人(甚至两者兼而有之)为特点。
无论如何,两种纤维、绿线和共程的目的都是同时执行多种功能,但并非在单一星级线内平行执行(为区分而见此问题),以有组织的方式相互之间相互转移控制权。
当使用纤维、绿线或共程时,您通常每个函数都有单独的堆叠。 (在技术上,不只是堆叠,而是整个执行环境是每个函数。 最重要的是, cpu 登记册。 ) 对于每一个线串, 每一个线串都有与同时运行的函数一样多的堆叠, 而线串正在根据程序逻辑执行每个函数。 当函数运行到尾端时, 它的堆叠就会被销毁。 因此, 堆叠的数量和寿命都是个王宫 。
注意我所说的“ 通常每个函数有一个单独的堆叠 ” 。 有堆叠和堆叠的 courutines 。 最显著的堆叠 c++ 执行是 推进. coroutine 和 微软 ppl 的 async/ wait 。 (然而, c++ 的可恢复功能 (a. k. a. a. “ 合成和等待 ” ) , 这些功能被建议到 c++/17 , 可能会使用没有堆叠的 comutines 。 )
C++标准图书馆的纤维建议即将提出。 还有一些第三方图书馆。 绿线在Python 和 Ruby 等语言中非常受欢迎。
20世纪80年代,Unix像兔子一样传播,大公司自己滚动。 Exxon拥有一个,历史也失去了数十个品牌。 许多执行者都决定如何留下记忆。
典型的 c 程序在记忆中平坦,有机会通过改变 brk () 值来增加。 典型的情况是, 堆积量略低于这个 brk 值, 增加 brk 增加了可用堆积量 。
单堆叠一般是堆积层下的一个区域, 它是一个内存的块块, 在下一个固定的内存区块的顶部之前, 没有任何价值。 下一个块块通常是代码, 在其时代著名的黑客之一的堆叠数据中, 可能被堆叠数据覆盖 。
一个典型的内存区块是 bss (一个零值块) , 在一个制造商的报价中, 意外没有零。 另一个是包含初始值的数据, 包括字符串和数字。 第三个是包含 Crt( cruntime) 、 主机、 函数和图书馆的代码 。
虚拟内存在 unix 中出现 。 许多限制 。 这些区块需要毗连, 或固定大小, 或现在订购特定方式, 没有客观的理由 。 当然, unix 之前的多立方体没有受到这些限制的影响 。 下面是一张图表, 显示这个时代的记忆布局 。
调
a couple of cents: 我认为, 绘制内存图形比较简单, 将会是件好事 :
调
箭头 - 显示生长堆叠和堆肥的位置, 进程堆叠大小有限制, 以 os 定义, 以线状线条参数为线状堆叠大小限制通常创建 api 。 通常以进程最大虚拟内存大小为限制, 例如32 位 2-4 gb 。
如此简单的方式:过程堆积对于过程和内部所有线条来说都是一般的, 用于记忆分配, 常见的情况是像 malloc () 。
堆栈是用于存储常见函数返回指针和变量的快速存储存储存储的快速内存, 被处理为函数调用中的参数, 本地函数变量 。
简单的说, 堆栈是创建本地变量的地方。 另外, 每次您调用一个子例程, 程序计数器( 下个机器指令的指针) 和任何重要的注册器, 有时参数会被推到堆栈上。 然后子例程内的任何本地变量都会被推到堆叠上( 并在那里使用 ) 。 当子例程完成时, 所有的事物都会从堆栈中跳出来。 pc 和 注册数据会得到并放回原位, 所以您的 progra 就会被推到堆叠上( 并在那里使用 ) 。
它是一个特殊的数据结构,可以跟踪不同大小的记忆区块及其分布状况。
在“古典”系统上, 堆叠指针是放在记忆底部开始的, 堆积指针是从顶部开始的, 并且它们相互向上发展。 如果它们重叠, 你就会脱离公羊。 但是, 与现代多孔的套索不起作用。 每条线必须有自己的堆叠, 并且它们可以动态地生成 。
(我将这一答案从另一个或多或少是本问题的代名词的问题移出。 )
您问题的答案是具体执行问题,可能因汇编者和处理结构而异。然而,这里是简单的解释。
堆叠和堆积都是从基本操作系统分配的内存区域(通常是虚拟内存,根据需要绘制成物理内存)。 在多轨环境中,每条线将有自己的完全独立的堆叠,但他们将共享堆叠。同时存取必须控制在堆积上,不可能在堆叠上。
堆积物,
堆积中含有一个用过的和自由的区块的链接列表。 堆积( 由新的或中转的) 上的新分配通过从一个自由区块中创建一个合适的区块来满足。 这需要更新堆积中的区块清单。 堆积中的区块的元信息也通常储存在堆积中, 保存在每个区块前面的小区域中。 当堆积中的新区块往往从下面的地址分配到更高的地址。 因此, 您可以将堆积视为一个堆积 o 。
调
堆叠堆叠
堆叠通常与名为堆叠指针的 cupu 上的特殊登记簿密切配合。 最初, 堆叠指针指向堆叠的顶部( 堆叠上的最高地址 ) 。 堆叠有将值推到堆叠上并将其从堆叠中弹出的特殊指令。 每一次推移都存储在堆叠指针当前位置的值, 并减少堆叠指针。 流行会检索堆叠指针指向的值, 然后增加堆叠指针( 不要) 。
调
能否在堆叠上而不是堆叠上分配函数 ?
否,函数(即本地变量或自动变量)的激活记录在堆栈上分配,不仅用于存储这些变量,还用于跟踪嵌套功能电话。
如何管理堆肥真的取决于运行时间环境。 c 使用中转器, c++ 使用新的, 但很多其他语言都有垃圾收集 。
然而,堆叠是一个更低层次的特征,它与处理器结构紧密相连。 当没有足够的空间时, 堆叠会生长成堆不会太难, 因为可以在处理堆叠的图书馆电话中执行。 然而, 堆叠的堆叠往往不可能增长, 因为堆叠溢出的时间太晚才被发现; 关闭行刑线是唯一可行的选择。