堆叠和堆肥是什么?它们实际上位于计算机的内存中在哪里?它们在多大程度上被操作时间或语言控制?它们的范围是什么?它们的大小是什么?它们大小是什么?一个的大小是什么使一个更快?


当前回答

虚拟内存中的每个过程的堆叠、堆积和数据 :

其他回答

a couple of cents: 我认为, 绘制内存图形比较简单, 将会是件好事 :

箭头 - 显示生长堆叠和堆肥的位置, 进程堆叠大小有限制, 以 os 定义, 以线状线条参数为线状堆叠大小限制通常创建 api 。 通常以进程最大虚拟内存大小为限制, 例如32 位 2-4 gb 。

如此简单的方式:过程堆积对于过程和内部所有线条来说都是一般的, 用于记忆分配, 常见的情况是像 malloc () 。

堆栈是用于存储常见函数返回指针和变量的快速存储存储存储的快速内存, 被处理为函数调用中的参数, 本地函数变量 。

20世纪80年代,Unix像兔子一样传播,大公司自己滚动。 Exxon拥有一个,历史也失去了数十个品牌。 许多执行者都决定如何留下记忆。

典型的 c 程序在记忆中平坦,有机会通过改变 brk () 值来增加。 典型的情况是, 堆积量略低于这个 brk 值, 增加 brk 增加了可用堆积量 。

单堆叠一般是堆积层下的一个区域, 它是一个内存的块块, 在下一个固定的内存区块的顶部之前, 没有任何价值。 下一个块块通常是代码, 在其时代著名的黑客之一的堆叠数据中, 可能被堆叠数据覆盖 。

一个典型的内存区块是 bss (一个零值块) , 在一个制造商的报价中, 意外没有零。 另一个是包含初始值的数据, 包括字符串和数字。 第三个是包含 Crt( cruntime) 、 主机、 函数和图书馆的代码 。

虚拟内存在 unix 中出现 。 许多限制 。 这些区块需要毗连, 或固定大小, 或现在订购特定方式, 没有客观的理由 。 当然, unix 之前的多立方体没有受到这些限制的影响 。 下面是一张图表, 显示这个时代的记忆布局 。

哇! 这么多答案,我觉得其中之一 没有得到正确的答案...

(在真实的计算机记忆中)在哪里?

堆栈是作为分配给您的程序图像的最高内存地址开始的内存,然后从那里降低值。它保留给所谓的函数参数和函数中使用的所有临时变量。

有两层楼:公营和私营。

私人堆积始于程序代码的最后一字节之后的16字节边界( 64比特程序)或8比特边界( 32比特程序),然后从中增加值。它也被称为默认堆积。

如果私人堆肥过大, 它会重叠堆叠区域, 如果堆叠太大, 堆叠也会重叠堆叠区域。 因为堆叠从更高的地址开始, 并一直往下工作到较低的地址, 适当的黑客可以使堆叠变得如此大, 它会超过私人堆肥区域, 并重叠代码区域。 那么, 技巧就是将代码区域重叠到足够大的地方, 从而可以连接到代码中。 这样做有点棘手, 你可能会冒程序崩溃的风险, 但是它很容易, 而且非常容易。

公用堆积在它自己的记忆空间中, 它不在您的程序图像空间之内。 如果记忆资源变得稀缺, 这个记忆将会被吸到硬盘上 。

2) 它们在多大程度上受到国家或语言运行时间的控制?

堆叠由程序员控制, 私人堆积由操作员管理, 公众堆积不为任何人控制, 因为它是一种操作员的服务-- 你提出请求, 要么被批准,要么被拒绝。

2(b) 其范围是什么?

它们都是全球性的,但内容可以是私人的,公共的,也可以是全球性的。

2(c) 由什么因素决定每个小组的大小?

您的编译器运行时间选项决定了堆叠和私有堆放的大小。公共堆放使用大小参数在运行时初始化。

2(d) 是什么使一个速度更快?

程序程序员如何使用它们来决定它们是“快”还是“慢”

ref:

https://norasandler.com/2019/02/18/Write-a-Compiler-10.html

https://learn.microsoft.com/en-us/windows/desktop/api/heapapi/nf-heapapi-getprocessheap

https://learn.microsoft.com/en-us/windows/desktop/api/heapapi/nf-heapapi-heapcreate

堆叠 :

堆叠上创建的变量将超出范围,自动交易。 与堆叠上的变量相比, 分配速度要快得多。 使用实际的堆叠数据结构执行。 存储本地数据、 返回地址、 参数通过时使用的方法。 当堆叠过多使用时, 可能会出现堆叠溢出( 大多来自无限或过深的循环, 非常大的配置) 。 堆叠上创建的数据可以在没有指针的情况下使用 。

堆积 :

在 c+++ 中, 堆积上的变量必须手动销毁, 并且绝不会掉出范围 。 数据通过删除、 删除或自由解脱而解脱。 与堆叠上的变量相比, 分配速度较慢。 需要时使用来分配块块数据供程序使用。 当有大量分配和交易位置时, 可能会发生碎裂 。 在 c+++ 或 c 中, 堆积上生成的数据将被指向指针, 并分别与新数据或中位相分配 。

例如:

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;

当调用函数时,当调用该函数的参数加上一些其他间接费用时,会将数据堆放到堆栈中。一些信息(例如返回何处)也存储在那里。当您在函数中声明变量时,该变量也会被分配到堆栈中。

分配堆栈非常简单, 因为您总是在分配的反向顺序中进行排列。 在输入函数时会添加堆叠材料, 当退出时相应的数据会被删除。 这意味着您往往会留在堆栈的狭小区域, 除非您调用许多函数来调用其他函数( 或者创建循环解决方案 ) 。

堆积堆是一个通用名称, 用于您将创建的数据放在哪里 。 如果您不知道您的程序将创建多少飞船, 您可能会使用新的( 或商场或等效的) 操作器来创建每艘飞船 。 此分配将会停留一段时间, 因此我们很可能释放的东西 以不同于我们创建的顺序 。

因此,堆积要复杂得多,因为最终会出现一些未使用的记忆区域,这些区域与块间断 — — 内存会变得支离破碎。 找到您需要的大小的自由记忆是一个困难的问题。 这就是为什么应该避免堆积( 尽管它仍然经常被使用 ) 。

执行堆叠和堆叠通常要到运行时间 / os. 通常游戏和其他功能对于性能至关重要的应用程序会创建自己的内存解决方案,从堆叠中抓取一大块内存,然后在内部将内存分离出来,以避免依赖 os 来进行内存。

只有当你的记忆用法与常规有很大不同时, 也就是在游戏中, 在一个巨大的操作中加载一个水平, 并且可以在另一个巨大的操作中将整个批量扔掉时, 这才是实际的。

内存中的物理位置比你想的要少, 这是因为一种叫做虚拟内存的技术, 它使得您的程序认为您可以进入某个地址, 物理数据在其他地方( 即使是在硬盘上!) 。 您获得的堆叠地址随着调用树越深, 顺序越大。 堆积的地址是无法预测的( 具体化) , 坦率地说并不重要 。