Moo*_*uck 12
它实际上比你想象的要复杂得多.操作系统会考虑"页面"中的所有内容,将RAM分成页面,将硬盘分成页面.当您的程序启动时,它会检查您的可执行文件占用多少内存,为它选择一些RAM页面,并将这些页面分配给您的程序.如果RAM中没有"可用"页面,它会占用RAM中较旧的一些页面,并将它们保存到隐藏在某处的硬盘驱动器中,然后将这些页面提供给您.
在程序中分配内存时,程序的内存管理器将尝试在操作系统分配给它的页面中找到一个空闲位置.如果还不够,它会向操作系统询问更多页面,并且操作系统会腾出更多空间并为您的应用程序提供更多页面.
如果您的程序有一段时间没有使用的页面(有时甚至是代码),操作系统可能会将该页面保存到硬盘驱动器,当程序再次尝试使用该页面时,操作系统会暂停程序,将页面重新加载到RAM中,然后恢复您的程序.
这是一个毫无意义的图表
C++ addresses RAM hard drive
+------------+ +------------+ +------------+
| 0x00010000 |\ ->| 0x00010000 | | 0x00010000 |
+------------+ X +------------+ +------------+
| 0x00020000 |/ ->| 0x00020000 | | 0x00020000 |
+------------+ +------------+ +------------+
| 0x00030000 |-->? /----->| 0x00030000 |
+------------+ / +------------+
| 0x00040000 |-----------/ | 0x00040000 |
+------------+
| etc |
Run Code Online (Sandbox Code Playgroud)
所以在这段代码中,你的代码的堆栈内存为0x00010000-0x0002FFFF,你已经分配了一些动态内存,那就是0x0004000.就像你知道的那样!实际上,当您访问0x0002000时,操作系统会说"哦,我已将您的那个页面存储在RAM地址0x00010000"中并为您读取这些值.您暂时没有触及0x00040000的页面,因此操作系统将其保存到硬盘驱动器位置0x00030000的硬盘驱动器,但如果您尝试使用它,它会将其带入RAM.操作系统尚未提供地址0x00030000,因此如果您尝试使用它,操作系统会告诉您该地址没有任何实际页面,并且您会收到分段错误(segfault).让这个有趣的是当你要求一个像矢量这样的大型连续块时,操作系统可以为您提供它所找到的任何旧页面,如果它们是连续的,则不必担心.它们看起来与您的程序相邻,这一切都很重要.
这也允许操作系统隐藏一个程序的存储器,使其无法读取或修改其他程序的存储空间.他们很安全!除了......有办法告诉操作系统在两个程序之间共享页面(尽管它们在每个程序中可能有不同的地址),允许它们共享页面.DLL这样做.
实际上,它比这复杂得多.
1)它是从RAM还是从硬盘或其他地方分配的?
在支持虚拟内存的现代系统/平台上,操作系统决定在何处以及如何分配/存储内存.系统也可以在内存或磁盘上将内存从一个地方移动到另一个地方.
2)为了以防万一,我可以从硬盘借内存吗?
管理内存的操作系统可以从磁盘中借用内存.
您还可以通过将数据存储在文件中来明确地从磁盘中借用内存.C和C++标准库(stdio.h和fstream)启用文件操作.