• 什么是堆叠和堆叠?
  • 他们在电脑记忆中身处何方?
  • 它们在多大程度上受到操作系统或语言运行时间的控制?
  • 其范围是什么?
  • 是什么决定了它们的大小?
  • 是什么让一个更快?

当前回答

当在加载代码和数据操作系统设置后创建一个进程时, 在数据结束和基于架构的地址空间顶端堆叠后, 程序在装入代码和数据操作系统设置后启动堆放

当需要更多堆积时, OSS 将动态分配, 堆积块总是几乎毗连

请参看请见brk(), sbrk()alloca()系统在 Linux 中调用

其他回答

感谢您一个很好的讨论,但作为一个真正的名人,我想知道指示的保存地点在哪里?在BEGINN的科学家们正在决定两个建筑之间(这里所有东西都被视为DATA和HARVARD,在那里保留了用于指示的记忆区和另一个数据区)。最后,我们用冯纽曼设计,现在一切都被认为是“相同的”。这让我在学习组装时很难接受。https://www.cs.virginia.edu/~evans/cs216/guides/x86.html因为他们谈论 登记册和堆叠指针。

上面的一切都在谈论DATA。我的猜测是,既然一个指令是定义的,有特定的内存足迹,它会放在堆叠上,因此所有在集成中讨论的“那些”登记册都放在堆叠上。 当然,随后的面向对象的编程也带来了指示和数据,并融合到一个动态结构中,现在指示也会被保存在堆叠上?

其他人直接回答了你的问题,但是,在试图理解堆叠和堆叠时,我认为,考虑传统的UNIX进程的记忆布局(没有线条和线条)是有益的。mmap()- 以基于分配器为基础。记忆管理词汇表网页上有一个内存布局图。

堆堆和堆堆堆传统上位于进程的虚拟地址空间的对面。当访问时,堆堆会自动增长,最多以内核设定的大小(可以与setrlimit(RLIMIT_STACK, ...)))当内存分配器援引brk()sbrk()系统呼叫,绘制更多页的物理内存 进入该过程的虚拟地址空间。

在没有虚拟内存的系统中,例如一些嵌入系统,通常适用同样的基本布局,但堆叠和堆积大小固定。然而,在其他嵌入系统(例如基于微芯片的微控制器)中,程序堆叠是一个单独的内存块,无法通过数据移动指示处理,只能通过程序流指示(调用、返回等)进行间接修改或阅读。多个堆叠。从这个意义上说,堆叠是CPU结构的一个元素。

最重要的一点是,堆积和堆叠是记忆分配方法的通用术语,可以多种不同方式加以实施,这些术语适用于基本概念。

  • 在一个堆叠的项目中,项目坐在另一堆的上方,按其放置的顺序排列,你只能删除顶端的项目(不折叠整件事情)。

    Stack like a stack of papers

    堆叠的简单性在于您不需要保存包含分配内存每一部分的记录的表格; 您所需要的唯一状态信息是到堆栈尾端的单指针。 要分配和取消分配, 您只需递增和缩减该单指针。 注意: 有时可以安装堆叠, 以开始于内存的顶部, 向下延伸, 而不是向上增长 。

  • 在堆积中,项目放置方式没有特定顺序。您可以按任何顺序接触和删除项目,因为没有明确的“顶部”项目。

    Heap like a heap of licorice allsorts

    高空分配需要完整记录什么是记忆分配,什么是记忆分配,什么不是,以及一些间接维护,以减少碎裂,发现毗连的内存部分大到足以满足要求的大小,等等。 内存可以在离开空闲空间的任何时候进行分配。 有时,内存分配器将执行维护任务,例如通过移动分配的内存或垃圾收集来消除内存的分散性,或者在运行时识别内存不再在范围之内的运行时间并进行分配。

这些图像应该能很好地描述 在堆叠和堆肥中分配和释放记忆的两种方式。

  • 它们在多大程度上受到操作系统或语言运行时间的控制?

    如前所述,堆叠和堆叠是一般术语,可以多种方式实施。呼叫堆叠存储与当前函数相关的信息, 如指向它从哪个函数调用, 以及任何本地变量。 因为函数调用其他函数, 然后返回, 堆叠会增长并缩放, 以便从调用堆栈往下更远的函数中保留信息。 一个程序实际上没有运行时间控制; 它由编程语言、 OS 甚至系统架构决定 。

    堆积是一个通用术语,用于动态和随机分配的任何内存;即失序。内存通常由操作系统分配,应用程序中调用 API 函数来分配。管理动态分配内存需要相当一部分管理费,通常由所用编程语言或环境的运行时间代码处理。

  • 其范围是什么?

    调用堆栈是一个低层次的概念, 以至于它与编程意义上的“ 范围” 无关。 如果您将一些代码拆解, 您将会看到与堆叠部分相对的指针样式引用, 但就更高层次的语言而言, 语言会强制实施它自己的范围规则 。 但是, 堆栈的一个重要方面是, 一旦一个函数返回, 任何本地的函数都会立即从堆叠中解开。 这与您所编程语言是如何工作的有关。 在堆放过程中, 它也很难定义。 范围是由操作系统所暴露的, 但是您的编程语言可能会增加它关于“ 范围” 在您的应用程序中是什么的规则 。 处理器结构和 OS 使用虚拟地址, 处理器可以翻译为物理地址, 并且有页面错误等 。 它们会跟踪哪些页面属于哪个应用程序。 但是, 您从不需要担心这一点, 因为您只是使用你编程语言用于分配和自由记忆的方法, 并检查错误( 如果由于任何原因分配/ 解析失败 ) 。

  • 是什么决定了每个孩子的大小?

    同样,它取决于语言、编译器、操作系统和架构。 堆叠通常是预先分配的, 因为根据定义它必须是连续的内存。 语言编译器或操作系统决定其大小。 您不会在堆叠中存储大量数据, 因此它会足够大, 永远不能被充分利用, 除非在无谓的循环( 例如“ 堆叠溢出 ” ) 或其他不寻常的编程决定下。

    对于任何可以动态分配的东西来说, 堆积是一个通用的术语。 取决于您看它的方式, 它的大小在不断变化。 在现代的处理器和操作系统中, 它的运作方式是非常抽象的, 所以通常你不需要担心它是如何在内心深处运作的, 除了( 在它允许你使用的语言中) 您不能使用你还没有分配到的记忆或者你已经释放的记忆。

  • 是什么让一个更快?

    堆叠速度更快, 因为所有自由内存总是毗连的 。 不需要保存自由内存所有部分的清单, 仅指堆叠当前顶部的单指针。 汇编者通常会将这个指针保存在特殊、 快速的文件中 。登记册登记簿更何况,堆叠上的后续操作通常集中在非常靠近的内存区内,这些内存区在非常低的水平上,对处理器置存的缓存器优化是有好处的。

哇,这么多答案,我觉得其中的某个人搞错了...

1) 它们在哪里以及是什么(在真实的计算机记忆中)?

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

有两层楼:公共楼和私人楼。

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

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

公用堆积层位于您的程序图像空间以外的自己的记忆空间中。 如果记忆资源变得稀缺, 这个记忆将会被吸到硬盘上 。

(2) 它们在多大程度上受到操作系统或语言运行时间的控制?

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

2(b) 其范围是什么?

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

2(c) 由什么因素决定其中每一方的大小?

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

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

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

俄联邦:

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+++ 中, 堆积上的变量必须手动销毁, 并且绝对不能脱离范围。 数据以delete, delete[],或free.
  • 相对于堆叠上的变量, 较慢分配速度 。
  • 用于按需分配一组数据供程序使用。
  • 当有大量拨款和交易时,就有可能支离破碎。
  • 在C++ 或C++ 或C中,在堆积上生成的数据将用指针指出,并用newmalloc两者分别。
  • 如果要求分配的缓冲量太大,则可以造成分配失败。
  • 如果您不知道运行时需要多少数据, 或者需要分配大量数据, 您就会使用这种数据 。
  • 负责内存泄漏

示例:

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;