C++ 中的 RAM、硬盘、堆栈和堆是啥?

Posted

技术标签:

【中文标题】C++ 中的 RAM、硬盘、堆栈和堆是啥?【英文标题】:What goes to RAM, Harddrive, Stack and Heap in C++?C++ 中的 RAM、硬盘、堆栈和堆是什么? 【发布时间】:2012-04-08 21:51:44 【问题描述】:

对于这些实例,在 C++ 中运行时,有人可以大致说明什么(硬盘、RAM、堆栈或堆):

局部/全局变量

类、方法和函数

指针

对象

堆栈/堆是否都位于物理 RAM 中?

如果有人可以在答案中包含硬件类比,我将不胜感激。 谢谢。

【问题讨论】:

我闻到了家庭作业或考试准备的味道 :) 只要问题被适当地标记,所有这些都可以。 不要混淆编程语言计算硬件。前者是一种语言,后者在你把它丢在地板上时就会中断。编程语言可用于指导计算机,但它们首先是一种抽象结构。 @Kerrek SB:如果我可以说,那么 C++ 会指示计算机最后将它们放在哪里? @Maiss:C++ 什么都不做。这是一种语言。您的编译器根据用该语言编写的程序为您的计算机创建机器代码指令。 【参考方案1】:

在 C++ 中,当您保存程序时,它会进入硬盘驱动器,当您开始编译和执行程序时,它会进入主内存 (RAM)。所有的堆栈和堆内存都是 ram 内存的一部分。

根据程序中的变量声明和函数调用分配内存。默认堆栈大小为 2 MB(来自谷歌搜索),它存储您程序的所有局部变量。

堆包含在运行时创建的所有数据,意味着通过mallocnew

【讨论】:

【参考方案2】:

所有这些都进入记忆。现在,“内存中”的定义取决于操作系统、编译器和链接器选项、可执行格式以及其他数百万个因素。

在许多现代操作系统上,当创建一个进程时,可执行文件会映射到内存中(这意味着为可执行文件保留了一个内存区域,但并不意味着该可执行文件已加载到该位置)。

某些操作系统会在访问可执行文件时加载部分可执行文件(请参阅“延迟加载”),这对于动态加载的库(Windows 上的 DLL 和类 UNIX 系统上的共享对象)更为常见。这主要影响函数的当前“位置”,它们或者作为可执行文件“在磁盘上”,或者如果可执行文件的那部分已被映射,则“在内存中”。

变量和所有其他程序数据进入内存。但是,任何使用虚拟内存运行的操作系统都可以在方便时将您程序的所有运行状态(包括堆栈和堆)交换到磁盘,然后再将其恢复以继续运行您的程序。

总之,您列表中的所有项目(变量、函数等)都在内存中,尽管可能不会一直存储在“物理 RAM”中。

【讨论】:

【参考方案3】:

这通常取决于操作系统,但通常是这样的:

一切都进入 RAM。二进制文件驻留在硬盘驱动器中,但在运行时会与相关库一起完全加载到 RAM 中。

堆栈和堆是实现细节,但它们也驻留在 RAM 中。

虽然加载到 RAM 中,但内存不能直接寻址。操作系统为每个进程分配虚拟内存。这意味着地址0x001实际上并不位于RAM中的0x001,而是表示虚拟地址空间中的一个地址。

编辑:澄清 op 的 cmets 之一:

二进制文件是在运行时完全加载还是部分加载?而且,这些二进制文件是仅在运行时访问一次还是持续从硬盘读取?

例如,在 MS 中,如果您链​​接到一个库,它将在运行时,在程序开始时完全加载。如果您以编程方式通过LoadLibrary() 加载它,它会在函数调用时加载到内存中,并且可以从内存中卸载。

【讨论】:

@GuySirton 我指定了,但最常见的是 RAM。 我相信他的观点是虚拟内存的一部分——即页面——可以并且将会被换出到磁盘。 是的。如果您(操作员)正在编写需要任何性能的 C++,那么虚拟内存实现细节非常重要。查看此***页面以开始使用:en.wikipedia.org/wiki/Paging 您能告诉我二进制文件在运行时是完全加载还是部分加载?而且,这些二进制文件是仅在运行时访问一次还是一直从硬盘读取? @Maiss 这取决于。例如,在 MS 中,如果您链​​接到一个库,它将在运行时,在程序开始时完全加载。如果通过LoadLibrary() 以编程方式加载它,它会在函数调用时加载到内存中,并且可以从内存中卸载。

以上是关于C++ 中的 RAM、硬盘、堆栈和堆是啥?的主要内容,如果未能解决你的问题,请参考以下文章

堆栈与堆栈和堆与堆

Java中的堆和栈以及堆栈的区别

如何将CPU,RAM,磁盘,碎片分配给ELK堆栈中的节点?

两种语言是不是在 ram 上使用相同的堆栈和堆?

从Java的堆栈到Equals和==的比較

当文件在 C++ 中打开并且我们开始读取时,整个文件是从硬盘加载到 RAM 还是一个块一个块地加载到 RAM 中?