【问题标题】:how does a program runs in memory and the way memory is handled by Operating system程序如何在内存中运行以及操作系统处理内存的方式
【发布时间】:2012-12-27 09:15:02
【问题描述】:

我不清楚进程正在执行时的内存管理 在运行期间

这是一个图表

我不清楚图片中的以下内容:

  • 1) 此图像所指的堆栈是什么?
  • 2) 什么是内存映射段,指的是文件映射?
  • 3) 堆与进程有什么关系。堆是仅在进程中处理还是由操作系统内核维护,然后当用户空间应用程序调用时由 malloc 分配内存空间(使用堆)?

文章提到 http://duartes.org/gustavo/blog/post/anatomy-of-a-program-in-memory/

虚拟地址空间,在 32 位模式下总是一个 4GB 的块 内存地址。这些虚拟地址映射到物理地址 按页表存储,

  • 4) 这是否意味着一次只有一个程序在占用整个 4 GB RAM 的内存中运行?

同一篇文章也提到

Linux 通过添加随机化堆栈、内存映射段和堆 到它们的起始地址的偏移量。不幸的是 32 位地址 空间非常紧凑,几乎没有随机化的空间 影响其有效性。

  • 5) 是指在进程中随机化堆栈还是指计算所有进程的空间后剩下的东西?

【问题讨论】:

  • 问题太多了。
  • 实际上已经一个星期了,我还无法理解这篇文章,这就是为什么我发布了即使你可以部分回答这将有助于可能其他人会回答另一部分等等跨度>

标签: c memory memory-management


【解决方案1】:

1) 该图像所指的堆栈是什么?

stack 用于分配局部变量和函数调用帧(包括函数参数、函数调用后返回的位置等)。

2) 什么是内存映射段,指的是文件映射?

Memory mapping segment 保存链接库。这也是分配mmap 呼叫的地方。通常,内存映射文件只是由文件支持的内存区域。

3) 堆与进程有什么关系。堆是仅在进程中处理,还是由操作系统内核维护,然后当用户空间应用程序调用时由 malloc(使用堆)分配内存空间?

heap 是特定于进程的,由进程本身管理,但是它必须从操作系统请求内存才能开始(并根据需要)。你是对的,这通常是分配malloc 调用的地方。但是,大多数malloc 实现使用mmap 来请求内存块,因此堆和内存映射段之间的区别实际上很少。实际上,堆可以被认为是内存映射段的一部分。

4) 这是否意味着一次只有一个程序在占用整个 4 GB RAM 的内存中运行?

不,这意味着程序可用的可寻址内存量限制为 4 GB RAM,在任何给定时间实际包含在内存中的内容取决于操作系统如何分配物理内存,并且超出了这个问题的范围。

5) 是指在一个进程中随机化堆栈还是指计算所有进程的空间后剩下的东西?

我从未见过任何暗示 4gb 空间“妨碍”操作系统使用的内存分配策略的有效性的东西。此外,正如@Jason 所指出的,堆栈、内存映射段和堆的位置是随机的“以防止可预测的安全漏洞,或者至少使它们比操作系统管理的每个进程都具有可执行文件的每个部分更难完全相同的虚拟内存位置。”具体来说,操作系统正在随机化堆栈、内存映射区域和堆的虚拟地址。需要注意的是,进程看到的所有内容都是virtual address,然后根据特定页面所在的位置映射到内存中的物理地址。更多关于虚拟地址和物理地址映射的信息可以在here找到。

这个关于分页的维基百科article 是学习操作系统如何管理进程之间的内存的一个很好的起点,并且是一个很好的资源来阅读以回答问题 4 和 5。简而言之,内存是按页面分配的进程,并且这些页面要么存在于主内存中,要么已被“分页”到磁盘中。当一个进程请求一个内存地址时,它会将页面从磁盘移动到主内存,如果需要,替换另一个页面。有多种页面替换策略可供使用,我建议您参阅这篇文章以详细了解每种策略的优缺点。

【讨论】:

  • 附带说明,整个大学课程都专门用于学习与您刚刚提出的问题相关的介绍性主题和基础知识,所以不要指望一夜之间就能学会. (虽然如果你这样做了,你的力量会更大!)
  • 非常感谢 dicarlo2 的帮助,如果您能给我指点您提到的大学课程的一些教程或书籍,我将不胜感激
  • @RegisteredUser 当然,在 UIUC 的计算机体系结构介绍课程的后半部分和 systems programming 课程的大约一半中简要提到了这些主题。后者可能与您提出的问题最相关,请参阅我提供的链接中的内存说明。
  • 我在 UIUC 听说过一个练习,它说要编写页表遍历,如果是的话,你有没有听说过或做过,你能给我 UIUC 网站上的任何链接吗? /跨度>
  • 我应该补充一点,大多数应用程序在运行时有不止一个堆栈,但必须至少有一个 - 属于加载程序创建的线程的一个,用于在应用程序执行入口点运行代码.大概就是图中提到的那个堆栈。
【解决方案2】:

Linux 通过将偏移量添加到它们的起始地址来随机化堆栈、内存映射段和堆。不幸的是,32 位地址空间非常紧张,几乎没有留给随机化的空间并妨碍了它的有效性。

我相信,在比较 32 位和 64 位的随机化能力时,本文更多地进行了概括。 3GB 的 32 位可寻址内存仍然是相当大的“移动”空间......它只是没有 64 位操作系统所能提供的那么多空间,并且有某些应用程序,例如图像-内存密集型的编辑器等,很容易用完他们可用的全部 3GB 可寻址内存。请记住,我说的是“可寻址”内存……这取决于平台,而不是系统中可用的物理内存量。

【讨论】:

  • 考虑到进程看到的所有内容都是虚拟地址,我什至不确定随机堆栈、内存映射段和堆段的开头会做什么。
  • 这是为了防止可预测的安全漏洞,或者至少使它们比操作系统管理的每个进程都将可执行文件的每个部分都放在完全相同的虚拟内存位置更难。
  • 啊,这句话绝对让我记忆犹新,现在我想起来了。该引用的上下文可能提到了安全问题,并且与性能无关,正如我认为当它说“有效性”时所指的那样。
【解决方案3】:

第 1 部分。堆栈 ...

一个函数可以调用一个函数,该函数可能调用另一个函数。通过每次迭代分配的任何变量最终都在堆栈上。并在每个函数退出时取消分配,因此是“堆栈”。您可能会考虑使用 Wikipedia 来了解这些东西...http://en.wikipedia.org/wiki/Stack_%28abstract_data_type%29

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-12
    • 1970-01-01
    • 2015-06-25
    • 1970-01-01
    • 1970-01-01
    • 2021-10-01
    • 2014-05-22
    • 1970-01-01
    相关资源
    最近更新 更多