- 什么是堆叠和堆叠?
- 他们在电脑记忆中身处何方?
- 它们在多大程度上受到操作系统或语言运行时间的控制?
- 其范围是什么?
- 是什么决定了它们的大小?
- 是什么让一个更快?
当前回答
短短
一个堆叠用于静态内存分配,一个堆叠用于动态内存分配,两者都存储在计算机的内存记录中。
详细细节
堆叠
堆栈是一个“ LIFO ” (最后的, 首先是) 数据结构, 由 CPU 相当密切地管理和优化。 函数每次声明一个新的变量时, 它就会被“ 挤压” 到堆栈。 然后, 每次函数退出, 所有被该函数推到堆栈的变量都会被解开( 也就是说, 它们会被删除 ) 。 一旦一个堆叠变量被解开, 内存区域就会被其他堆叠变量所利用 。
使用堆叠存储变量的优点是存储存储器的内存为您所管理。 您不需要手动分配内存, 也无需在不再需要时解开内存。 此外, 因为 CPU 组织堆叠内存的效率非常高, 读写到堆叠变量的速度非常快 。
更多可以找到在这里.
堆肥
您计算机的存储器中, 堆积是一个区域, 没有自动为您管理, 也没有由 CPU 进行严格管理。 它是一个更自由的存储区( 并且更大 ) 。 要在堆积上分配存储器, 您必须使用 C 函数内嵌的 malloc () 或 calloc () 。 一旦您在堆积上分配了存储器, 您就有责任使用自由的( ) 来在不再需要该存储器时处理该存储器 。
如果您不这样做, 您的程序将会有所谓的内存泄漏。 也就是说, 堆堆上的内存仍将被搁置( 并且无法用于其它进程 ) 。 正如我们在调试部分看到的那样, 有一个工具被称为Valgrind Valgrind Valgrind 瓦格林它可以帮助你发现内存漏。
与堆叠不同, 堆积的大小没有变量大小限制( 除了您的计算机的明显物理限制之外 ) 。 堆积的内存读和书写要慢一点, 因为人们必须用指针来访问堆积的内存。 我们很快会讨论指针问题 。
与堆叠不同的是,在堆积上创建的变量可以被任意函数进入,在您的程序中的任何地方。堆积变量在范围上基本上是全球性的。
更多可以找到在这里.
堆栈上分配的变量直接存储到内存中, 访问此内存的时间非常快, 程序编译时会处理其分配问题。 当函数或方法调用另一个函数, 转而调用另一个函数等时, 所有这些函数的履行将一直暂停, 直到最后一个函数返回其值。 堆栈总是保留在 LIFO 的顺序中, 最新的保留区块总是要解开的下一个块块。 这样可以非常简单地跟踪堆叠, 从堆叠中释放一个块只是调整一个指针而已 。
堆积上分配的变量的内存在运行时间分配, 访问此内存的时间稍慢一点, 但堆积大小仅受虚拟内存大小的限制。 堆积的元素不互相依赖, 随时可以随机访问。 您可以随时分配块块, 并随时释放它。 这让跟踪堆积中哪些部分在任何特定时间分配或自由, 变得更加复杂 。
如果您确切知道在编译时间之前需要分配多少数据, 您可以使用堆叠, 而它并不太大。 如果您不知道运行时需要多少数据, 或者需要分配很多数据, 您可以使用堆叠 。
在一个多轨情况下, 每串线索将有自己的完全独立的堆叠, 但是它们会共享堆叠 。 堆叠是特定的线条, 堆叠是特定的应用程序 。 堆叠很重要, 在例外处理和丝线处决中需要考虑 。
每一串线索都有堆叠, 而通常应用程序只有一堆(尽管不同类型分配的多堆线索并不罕见) 。
运行时,如果应用程序需要更多堆积,它可以从自由存储中分配内存,如果堆叠需要内存,它可以从为应用程序分配的内存中分配内存。
来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来,来你的问题的答案.
它们在多大程度上受到操作系统或语言运行时间的控制?
当线索创建时, OS 会为每个系统级线索分配书架。 通常情况下, OS 会被语言运行时间调用来分配应用程序的堆积 。
更多可以找到在这里.
其范围是什么?
上方已经给出了 。
“如果你确切知道在编译时间之前你需要分配多少数据,你可以使用堆叠。它并不太大。如果你不知道运行时你需要多少数据,或者你需要分配很多数据,你可以使用堆叠。”
更多可见于在这里.
是什么决定了每个孩子的大小?
堆叠的大小由OS当创建线索时。 程序启动时会设置堆积的大小, 但随着空间需要, 堆积会变大( 分配器要求操作系统的内存更多 ) 。
是什么让一个更快?
堆叠分配速度要快得多, 因为它实际上所做的就是移动堆叠指针。 使用记忆池, 您可以从堆积分配中获取相似的性能, 但是这伴随着一个稍微增加的复杂性和它自己的头痛。
此外,堆叠对堆积不仅是一种绩效考量;它也告诉你很多关于物体预期寿命的情况。
详情可从在这里.
其他回答
堆叠当您调用函数时,该函数的参数加上一些其他间接费用被放在堆栈中。有些信息(例如返回后将到何处)也存储在那里。当您在函数中声明变量时,该变量也分布在堆栈中。
拆分堆栈很简单, 因为您总是按照您分配的反向顺序进行排列。 在输入函数时添加堆叠材料, 当退出时相应数据将被删除。 这意味着您倾向于留在堆叠的小区域内, 除非您调用许多函数来调用其他函数( 或创建循环解决方案 ) 。
堆肥堆积是一个通用的名称, 用于您将创建的数据放在哪里 。 如果您不知道您的程序要创建多少宇宙飞船, 您可能会使用新的( 或商略或等效的) 操作员来创建每艘宇宙飞船 。 此分配将会停留一段时间, 因此我们很可能释放的东西, 与我们创建的顺序不同 。
因此,堆积要复杂得多,因为最终会出现一些未使用的内存区域,这些区域与块状的内存间断 — — 内存会变得支离破碎。 找到您需要的大小的自由内存是一个困难的问题。 这就是为什么应该避免堆积(尽管它仍然经常被使用 ) 。
执行 执行 执行堆叠和堆叠的操作通常要到运行时间/操作系统。 通常游戏和其他功能至关重要的应用程序会创造自己的内存解决方案,从堆叠中抓取大量内存,然后在内部将内存分离出来,以避免依赖操作系统进行内存。
只有当你的记忆用法与常规有很大不同时, 也就是在游戏中, 在一个巨大的操作中加载一个水平, 并且可以在另一个巨大的操作中将整个批量扔掉时, 这才是实际的。
内存物理位置这比你想的要少 因为一种技术叫做虚拟内存这使得您的程序认为您可以访问某位地址, 物理数据在其他地方( 甚至是硬盘上! ) 。 您获得的堆叠地址随着您的呼叫树越深, 顺序越大。 堆放的地址是不可预知的( 具体化) , 坦率地说并不重要 。
您可以用堆叠做一些有趣的事情。 例如, 您的函数像单花(假设你能够通过有关其使用的大量警告) 这是一种专门用堆叠而不是堆叠来记忆的 中转器形式。
也就是说, 堆叠式的记忆错误是我经历过的最糟糕的记忆错误。 如果您使用堆积式内存, 并超越了分配区块的界限, 您就有一个很好的机会触发断段断层断层。 ( 不是100%: 您的区块可能附带地与先前分配的区块毗连 。 ) 但是由于堆叠上创建的变量总是相互连结, 边框中的写法可以改变另一个变量的值。 我了解到, 只要我感到我的程序不再遵守逻辑法则, 它可能就是缓冲溢出 。
几分钱:我想,画出内存图形和简单一些是件好事:
箭头 - 显示生长堆叠和堆叠、流程堆叠大小的极限, 以 OS 定义, 通常由线条中的线状堆叠大小的参数来设定 API 。 厚通常通过进程限制最大虚拟内存大小, 例如32 位 2 - 4 GB 。
简单的方法就是简单的方法:过程堆叠对于过程和内部所有线条都是一般的, 用于记忆分配, 通常使用类似的方式中偏().
Stack 是常见情况下存储的快速内存, 用于存储函数返回指针和变量, 处理为函数调用参数, 本地函数变量 。
什么是堆叠?
堆叠是一堆物体, 通常是排列整齐的物体。
计算机结构中的堆叠是数据以 " 最先进 " 方式添加或删除的内存区域。
在多行应用程序中,每串线索都有自己的堆叠。
什么是堆积物?
堆积成堆的杂乱无章的堆积物,
在计算结构中,堆积是一个动态分配的内存领域,由操作系统或内存管理库自动管理。
在方案执行期间,堆积物上的内存被分配、分配和调整,并定期调整大小,这可能导致一个称为碎裂的问题。
当内存物体在小空格内分配时,就会发生碎片,而内存物体之间的空格太小,无法再持有更多的内存物体。
净结果为无法用于进一步分配内存的堆积空间的百分比。
两者加在一起
在一个多行应用程序中, 每串线索都有自己的堆叠。 但是, 所有不同的线条都会共享堆叠 。
因为不同的线条在一个多行应用程序中共享堆积, 这还意味着线条之间必须有一些协调, 以免它们试图同时访问和操作堆积中的同一块内存 。
哪个速度更快 堆叠还是堆叠 为什么?
堆叠比堆积要快得多
这是因为记忆在堆叠上分配的方式。
堆疊上的内存分配和移动堆叠指针一样简单。
对于新编程的人来说,
因为堆栈很小, 当您知道数据需要多少内存时, 或者如果您知道数据大小非常小时, 您会想要使用它 。
最好在知道数据需要大量内存时使用堆积, 或者你只是不确定你需要多少内存(如动态数组)。
Java 内存模型
堆栈是存储本地变量(包括方法参数)的内存区域。当涉及到对象变量时,这些只是堆积中实际对象的引用(指针)。
每次一个对象被即时化时,都会留出一块堆积内存以保持该对象的数据(状态)。由于对象可以包含其他对象,有些数据实际上可以保留这些嵌套对象的引用。
因为有些答案没有被选中,所以我会贡献我的力量。
令人惊讶的是,没有人提到,不仅在外来语言(邮政(邮政)或平台(英特机Itium)中,而且在互联网上,都能找到多个(即与运行的OS级别线索数量无关)调呼堆叠(即与运行的OS级别线索数量无关)纤维纤维, 绿线以及一些执行《公约》和《公约》共管.
纤维、绿线和合金在许多方面都相似,导致许多混乱。 纤维和绿线之间的区别在于前者使用合作性多任务,而后者可能具有合作性或先发制人(甚至两者兼而有之)的特点。 关于纤维和合金之间的区别,请参看在这里.
无论如何,两种纤维、绿线和共程的目的都具有同时执行的多重功能,但是,否平行平行(见这个问题在一个OS级线内,以有组织的方式将控制权相互交替转移。
当使用纤维、绿线或合金时,你通常通常每个函数都有单独的堆叠 。 (在技术上, 不只是堆叠, 而整个执行环境是每个函数。 最重要的是, CPU 注册 。) 对于每串线索, 都有与同时运行的函数一样多的堆叠, 并且线索正在根据程序逻辑执行每个函数之间切换。 当一个函数运行到尾端时, 它的堆叠会被销毁 。 因此,堆叠的数量和寿命是动态的,并且不取决于操作系统级别线索的数量 !
请注意,我说过: "通常通常每个函数有一个单独的堆叠。堆叠和无文最引人注意的堆叠式C++的C++实施软 软 软 软 软 体和微软 PPPL数(_S)async/await
。 (然而, C++'s可恢复功能(a.k.a. " )async
和await
" (C++17提案,可能使用无堆叠的共程。 )
C++标准图书馆的Fibers提案即将提出。还有第三方。图书馆图书馆绿色线在Python和Ruby等语言中极为流行。