- 什么是堆叠和堆叠?
- 他们在电脑记忆中身处何方?
- 它们在多大程度上受到操作系统或语言运行时间的控制?
- 其范围是什么?
- 是什么决定了它们的大小?
- 是什么让一个更快?
当前回答
堆叠当您调用函数时,该函数的参数加上一些其他间接费用被放在堆栈中。有些信息(例如返回后将到何处)也存储在那里。当您在函数中声明变量时,该变量也分布在堆栈中。
拆分堆栈很简单, 因为您总是按照您分配的反向顺序进行排列。 在输入函数时添加堆叠材料, 当退出时相应数据将被删除。 这意味着您倾向于留在堆叠的小区域内, 除非您调用许多函数来调用其他函数( 或创建循环解决方案 ) 。
堆肥堆积是一个通用的名称, 用于您将创建的数据放在哪里 。 如果您不知道您的程序要创建多少宇宙飞船, 您可能会使用新的( 或商略或等效的) 操作员来创建每艘宇宙飞船 。 此分配将会停留一段时间, 因此我们很可能释放的东西, 与我们创建的顺序不同 。
因此,堆积要复杂得多,因为最终会出现一些未使用的内存区域,这些区域与块状的内存间断 — — 内存会变得支离破碎。 找到您需要的大小的自由内存是一个困难的问题。 这就是为什么应该避免堆积(尽管它仍然经常被使用 ) 。
执行 执行 执行堆叠和堆叠的操作通常要到运行时间/操作系统。 通常游戏和其他功能至关重要的应用程序会创造自己的内存解决方案,从堆叠中抓取大量内存,然后在内部将内存分离出来,以避免依赖操作系统进行内存。
只有当你的记忆用法与常规有很大不同时, 也就是在游戏中, 在一个巨大的操作中加载一个水平, 并且可以在另一个巨大的操作中将整个批量扔掉时, 这才是实际的。
内存物理位置这比你想的要少 因为一种技术叫做虚拟内存这使得您的程序认为您可以访问某位地址, 物理数据在其他地方( 甚至是硬盘上! ) 。 您获得的堆叠地址随着您的呼叫树越深, 顺序越大。 堆放的地址是不可预知的( 具体化) , 坦率地说并不重要 。
其他回答
堆堆叠
- 非常快速接入
- 不必明确排除可变变量
- 由CPU有效管理空间,内存不会分散
- 仅本地变量
- 对堆叠大小的限制(取决于OS)
- 变量无法调整大小
堆肥
- 可在全球范围内访问变量
- 内存大小无限制
- (相对)获取较慢
- 没有保证有效使用空间的保证,随着时间推移,记忆可能会变得支离破碎,因为分配了记忆区块,然后释放了
- 您必须管理内存( 您负责分配和释放变量) 。
- 可使用 elloc () 调整变量大小
堆叠 :
- 存储在计算机内存中 就像堆积物一样
- 堆叠上创建的变量将超出范围, 自动进行交易 。
- 与堆积上的变量相比,分配速度要快得多。
- 采用实际的堆叠数据结构。
- 存储本地数据, 返回地址, 用于通过参数 。
- 当堆叠使用过多时(大部分来自无限重现或过深重重循环,分配量很大), 堆叠就会溢出。
- 在堆栈上创建的数据可以不用指针使用 。
- 如果您确切知道在编译时间之前需要分配多少数据, 并且数据并不太大, 您就会使用堆叠 。
- 通常在程序启动时已经确定了最大尺寸 。
热量 :
- 存储在计算机内存 和堆叠一样。
- 在 C+++ 中, 堆积上的变量必须手动销毁, 并且绝对不能脱离范围。 数据以
delete
,delete[]
,或free
. - 相对于堆叠上的变量, 较慢分配速度 。
- 用于按需分配一组数据供程序使用。
- 当有大量拨款和交易时,就有可能支离破碎。
- 在C++ 或C++ 或C中,在堆积上生成的数据将用指针指出,并用
new
或malloc
两者分别。 - 如果要求分配的缓冲量太大,则可以造成分配失败。
- 如果您不知道运行时需要多少数据, 或者需要分配大量数据, 您就会使用这种数据 。
- 负责内存泄漏
示例:
int foo()
{
char *pBuffer; //<--nothing allocated yet (excluding the pointer itself, which is allocated here on the stack).
bool b = true; // Allocated on the stack.
if(b)
{
//Create 500 bytes on the stack
char buffer[500];
//Create 500 bytes on the heap
pBuffer = new char[500];
}//<-- buffer is deallocated here, pBuffer is not
}//<--- oops there's a memory leak, I should have called delete[] pBuffer;
CPU堆和堆肥与CPU和登记簿如何与记忆工作、机器组合语言如何运作、而不是高层次语言本身有实际联系,即使这些语言能决定小事。
所有现代CPU都与“相同”微处理理论合作: 它们都基于所谓的“ 注册者” 和一些“ 堆叠” 来取得性能。 所有 CPU 从一开始就有堆叠登记簿, 并且他们总是在这里, 正如我所知。 议会语言从一开始就是相同的, 尽管有各种变化... 直到微软及其中间语言(IL) 改变了范式, 有了OO虚拟机组装语言。 因此, 我们将来可以有一些 CLI/ CIL CPU (一个MS项目) 。
CPU有堆叠登记册来加速存取记忆,但与其他登记册相比,这些登记册有限,无法完全获取进程的所有可用内存。 这就是为什么我们谈论堆叠和堆积分配的原因。
简而言之,总的来说,堆积是慢慢的,用于“全球”实例和对象内容,因为堆叠的体积很小,速度很快,用于“本地”变量和参考(隐藏的指针要忘记管理它们)。
所以当我们用一种方法使用新关键字时, 引用( int) 是在堆叠中创建的, 但是对象及其所有内容( 价值类型以及对象) 都在堆积中创建, 如果我记得的话。 但是本地基本值类型和阵列是在堆叠中创建的 。
内存存存取的差别在于单元格参考级别:处理堆积,即整个过程的记忆,在处理CPU登记册方面要求比处理堆叠更为复杂,因为如果我记得,CPU堆叠登记册被用作基地址,因此,处理堆积存存存存取的差别就大于当地“更多”的堆叠。
这就是为什么当我们有非常长或无限的循环电话或循环时, 我们很快地被堆积物溢出, 而不冻结现代电脑上的系统...
C# Heap(ing) Vs Stack(ing) in.NET
https://en.wikipedia.org/wiki/Memory_management
https://en.wikipedia.org/wiki/Stack_register
大会语文资源:
堆叠当您调用函数时,该函数的参数加上一些其他间接费用被放在堆栈中。有些信息(例如返回后将到何处)也存储在那里。当您在函数中声明变量时,该变量也分布在堆栈中。
拆分堆栈很简单, 因为您总是按照您分配的反向顺序进行排列。 在输入函数时添加堆叠材料, 当退出时相应数据将被删除。 这意味着您倾向于留在堆叠的小区域内, 除非您调用许多函数来调用其他函数( 或创建循环解决方案 ) 。
堆肥堆积是一个通用的名称, 用于您将创建的数据放在哪里 。 如果您不知道您的程序要创建多少宇宙飞船, 您可能会使用新的( 或商略或等效的) 操作员来创建每艘宇宙飞船 。 此分配将会停留一段时间, 因此我们很可能释放的东西, 与我们创建的顺序不同 。
因此,堆积要复杂得多,因为最终会出现一些未使用的内存区域,这些区域与块状的内存间断 — — 内存会变得支离破碎。 找到您需要的大小的自由内存是一个困难的问题。 这就是为什么应该避免堆积(尽管它仍然经常被使用 ) 。
执行 执行 执行堆叠和堆叠的操作通常要到运行时间/操作系统。 通常游戏和其他功能至关重要的应用程序会创造自己的内存解决方案,从堆叠中抓取大量内存,然后在内部将内存分离出来,以避免依赖操作系统进行内存。
只有当你的记忆用法与常规有很大不同时, 也就是在游戏中, 在一个巨大的操作中加载一个水平, 并且可以在另一个巨大的操作中将整个批量扔掉时, 这才是实际的。
内存物理位置这比你想的要少 因为一种技术叫做虚拟内存这使得您的程序认为您可以访问某位地址, 物理数据在其他地方( 甚至是硬盘上! ) 。 您获得的堆叠地址随着您的呼叫树越深, 顺序越大。 堆放的地址是不可预知的( 具体化) , 坦率地说并不重要 。
在下面的 C# 代码中
public void Method1()
{
int i = 4;
int y = 2;
class1 cls1 = new class1();
}
下面是内存管理的方法
Local Variables
只需在堆叠中进行函数调用, 就会持续多久。 堆放堆放的堆放量用于那些我们一生中并不真正了解的变量, 但是我们期望它们会持续一段时间。 在大多数语言中, 关键是我们在编译时知道一个变量有多大, 如果我们想将其存储在堆放堆放中, 就必须知道它有多大 。
对象( 大小随更新而不同 ) 跳到堆积上, 因为我们不知道在创建时它们会持续多久 。 在许多语言中, 堆积是垃圾, 以寻找不再有任何引用的对象( 如 cls1 对象 ) 。
在 Java 中, 大多数对象都直接进入堆肥中。 在 C / C++ 等语言中, 支架和类通常可以在不与指针打交道时留在堆叠中 。
更多信息,请访问以下网站:
Timmurphy. org 表示堆叠和堆积记忆分配的差别。
此处 :
本条是上述情况的来源:6个重要的.NET概念:堆叠、堆积、价值类型、参考类型、拳击和拆箱-代码项目
但要知道它可能含有一些不准确之处。