4

这个问题是在一次采访中问我的,我的回答是“计算机内存”。但具体在哪里……?是随机存取存储器还是硬盘?

4

5 回答 5

7

他们可能正在寻找“堆”。这是一个与“堆栈”分开的内存区域,“堆栈”是存储所有局部变量、参数、返回值等的地方。是的,它们都在 RAM 中,而不是在硬盘上。

于 2010-08-13T04:33:14.807 回答
4

动态分配的内存是从通常称为“堆”的内存中分配的。

在 C++ 中,我们确实有两个“堆”(认为它们在技术上可能(或可能不是)是同一个区域)。malloc()(和family)分配的内存来自“堆”,而new(和family)分配的内存来自“free store”。

请注意,“堆”和“免费存储”都是计算机科学“堆”特定实例的名称。

语言定义没有定义由实现定义的“堆”或“自由存储”的含义。此外,操作系统将在内存页面发生的事情中发挥作用,但这超出了大多数应用程序的范围。

在计算机科学中,术语“堆栈”被用作一种简单的教学工具。它定义了一个用于跟踪函数调用的内存区域,与“堆”不同。在现代操作系统中,这是一个过于简单的定义。因此,运行时“堆栈”现在通常作为“堆”的一部分实现(这具有额外的优点,即您无需尝试在运行时跟踪堆/堆栈是否发生冲突。它还用作安全预防措施因为粉碎堆栈并获得确定性结果变得更加困难)。

于 2010-08-13T04:57:18.480 回答
3
  1. C++ 标准没有提到与 operator new 或动态内存分配有关的“堆”一词。因此,“堆”可能用常见的说法来表示与自动变量的存储区域不同的内存

  2. C++ 标准在脚注中声明 - “目的是 C++ 的内存模型与 ISO/IEC 9899 编程语言 C 的内存模型兼容。”

  3. 当我提到 C 标准时,它也没有提到任何关于“堆”的内容。

所以总而言之,最好假设动态内存分配的实际存储是未指定的(行为,对于格式良好的程序构造和正确的数据,这取决于实现。)

最后一点。

4.重要的是要记住'placement new'不会分配任何内存。相反,它使用预先分配的内存(作为参数传递给它)来构造对象。

于 2010-08-13T05:25:12.453 回答
2

在现代 PC、工作站或服务器机器上,“是随机存取存储器还是硬盘驱动器?”的答案。是:都不是。它分配在虚拟内存中。当它第一次被分配时,给你的虚拟地址可能没有任何物理存在。在第一次访问时,它将在 RAM 中物理实例化,但如果 R​​AM 需要用于其他用途,则稍后可能会将其移动到磁盘或其他交换设备上的存储中。在随后尝试访问它时,它将再次被移回 RAM。

这只是虚拟内存的非常非常基本的解释。如果您真的想了解,请阅读维基百科或谷歌上的一些文章。

于 2010-08-13T06:32:47.583 回答
1

简要总结一下——一个词的答案可能是“堆”。但是,所谓的堆栈或堆实际上是依赖于上下文的。例如,

有关堆栈,请参见Intel 编程指南第 6.2 节。'SS' 是堆栈段,它提供了一个连续的地址空间。当你调用一个函数时,它的返回地址、传递的参数和局部变量都分配在这个段上——称为“堆栈”。如果你有一个指针变量(比如 char * p),那么这个变量是在堆栈上分配的,但是内存是在 malloc() 或 C 上调用“new”时分配的,C++ 是在数据段上分配的(DS ) .另外,请参阅斯坦福教程.所以,不仅仅是增加SS中的堆栈顶部以转到下一个内存地址,现在处理器必须进行地址转换-检查地址是否在进程地址范围内,将虚拟地址拆分为段+偏移量,获取特定地址的值。

因此,这里对“堆栈”和“堆”的讨论与处理器架构密切相关——当我们处理像 C、C++ 这样的语言时。

对于 Java,一切都在堆上完成 - 这是所有 Java 进程的公共存储区域 - JVM 规范(参见第 3.5 和 3.6 节)说每个 JVM 线程都有自己的私有堆栈 - 存储堆栈帧 - 其中包括传递的参数,局部变量等。最重要的是,这些堆栈帧可以从堆中分配,不需要顺序寻址。除此之外,java 还提供了类似 C 的 Native 方法栈。

但是,我猜在面试环境中,最好说“堆”——如果被要求的话,只考虑详细说明。

于 2010-08-13T06:10:15.157 回答