虚拟内存的最大可寻址空间是多少?
看到这个问题被问了很多次。但找不到合理的答案。虚拟内存的实际限制是多少?
它是CPU的最大可寻址大小吗?例如如果CPU是32位最大是4G?
还有一些文本将其与硬盘区域相关。但我找不到这是一个很好的解释。有人说它是CPU生成的地址。
我们看到的所有地址都是虚拟地址吗?例如,我们在使用 GDB 调试程序时看到的内存位置。
CPU生成虚拟地址的历史原因?一些文本可互换地使用虚拟地址和逻辑地址。有什么不同?
Saw this questions asked many times. But couldn't find a reasonable answer. What is actually the limit of virtual memory?
Is it the maximum addressable size of CPU? For example if CPU is 32 bit the maximum is 4G?
Also some texts relates it to hard disk area. But I couldn't find it is a good explanation. Some says its the CPU generated address.
All the address we see are virtual address? For example the memory locations we see when debugging a program using GDB.
The historical reason behind the CPU generating virtual address? Some texts interchangeably use virtual address and logical address. How does it differ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不幸的是,答案是“视情况而定”。你没有提到操作系统,但当你提到GDB时你暗示了linux。我会尽量在回答中做到完全笼统。
基本上存在三种不同的“地址空间”。
第一个是逻辑地址空间。这是指针的范围。现代(386 或更好)具有内存管理单元,允许操作系统使您的实际(物理)内存出现在任意地址。对于典型的台式机,这是以 4KB 块的形式完成的。当程序访问某个地址的内存时,CPU 将查找该逻辑地址对应的物理地址,并将其缓存在 TLB(转换后备缓冲区)中。这允许三件事:首先,它允许操作系统为每个进程提供尽可能多的地址空间(最多可达指针的整个范围 - 或者如果有 API 允许程序映射/取消映射其地址空间的部分,则超出范围) )。其次,它允许通过切换到不同的内存映射来完全隔离不同的程序,从而使一个程序不可能损坏另一个程序的内存。第三,它为开发人员提供了调试帮助——随机损坏的指针可能指向一些根本没有映射的地址,导致“分段错误”或“无效页面错误”或其他任何情况,术语因操作系统而异。
第二个地址空间是物理内存。它只是你的 RAM——你的 RAM 数量是有限的。也可能有具有内存映射 I/O 的硬件 - 看起来像 RAM 的设备,但它实际上是一些硬件设备,例如 PCI 卡,或者可能是视频卡上的内存等。
第三种类型的地址是虚拟地址空间。如果物理内存 (RAM) 少于程序所需,操作系统可以通过只让程序产生拥有大量 RAM 的错觉来模拟拥有更多 RAM,而实际上只有一部分是 RAM,其余的是在“交换文件”中。例如,假设您的机器有 2MB 的 RAM。假设一个程序分配了4MB。将会发生的情况是操作系统将保留 4MB 的地址空间。操作系统将尝试将这 4MB 中最近/最常访问的部分保留在实际 RAM 中。任何不经常/最近访问的部分都将复制到“交换文件”。现在,如果程序触及实际不在内存中的 4MB 部分,CPU 将生成“页面错误”。操作系统会找到一些最近未被访问过的物理内存并“调入”该页面。它可能必须先将该内存页的内容写入页面文件,然后才能分页访问正在访问的数据。这就是它被称为交换文件的原因 - 通常,当它从交换文件中读取某些内容时,它可能必须先写出一些内容,从而有效地将内存中的内容与磁盘上的内容交换。
典型的MMU(内存管理单元)硬件会跟踪哪些地址被访问(即读取)和修改(即写入)。典型的分页实现通常会在分页时将数据保留在磁盘上。这允许它“丢弃”未修改的页面,从而避免在交换时写出该页面。典型的操作系统会定期扫描页表并保留某种数据结构,使其能够智能、快速地选择哪块物理内存未被修改,并随着时间的推移建立有关内存的哪些部分经常更改以及哪些部分发生更改的信息不。
典型的操作系统通常会温和地调出不经常更改的页面(温和地因为它们不想生成太多的磁盘 I/O,从而干扰您的实际工作)。这使得它可以在交换操作需要内存时立即丢弃页面。
典型的操作系统将尝试使用所有“未使用”的内存空间来“缓存”(保留副本)所访问的文件片段。内存比磁盘快数千倍,因此如果经常读取某些内容,则将其存储在 RAM 中会快得多。通常,虚拟内存实现将与该“磁盘高速缓存”结合作为可以快速回收用于交换操作的内存源。
编写一个有效的虚拟内存管理器是极其困难的。它需要动态地适应不断变化的需求。
典型的虚拟内存实现感觉非常慢。当机器开始使用远多于 RAM 的内存时,整体性能会变得非常非常糟糕。
Unfortunately, the answer is "it depends". You didn't mention an operating system, but you implied linux when you mentioned GDB. I will try to be completely general in my answer.
There are basically three different "address spaces".
The first is logical address space. This is the range of a pointer. Modern (386 or better) have memory management units that allow an operating system to make your actual (physical) memory appear at arbitrary addresses. For a typical desktop machine, this is done in 4KB chunks. When a program accesses memory at some address, the CPU will lookup where what physical address corresponds to that logical address, and cache that in a TLB (translation lookaside buffer). This allows three things: first it allows an operating system to give each process as much address space as it likes (up to the entire range of a pointer - or beyond if there are APIs to allow programs to map/unmap sections of their address space). Second it allows it to isolate different programs entirely, by switching to a different memory mapping, making it impossible for one program to corrupt the memory of another program. Third, it provides developers with a debugging aid - random corrupt pointers may point to some address that hasn't been mapped at all, leading to "segmentation fault" or "invalid page fault" or whatever, terminology varies by OS.
The second address space is physical memory. It is simply your RAM - you have a finite quantity of RAM. There may also be hardware that has memory mapped I/O - devices that LOOK like RAM, but it's really some hardware device like a PCI card, or perhaps memory on a video card, etc.
The third type of address is virtual address space. If you have less physical memory (RAM) than the programs need, the operating system can simulate having more RAM by giving the program the illusion of having a large amount of RAM by only having a portion of that actually being RAM, and the rest being in a "swap file". For example, say your machine has 2MB of RAM. Say a program allocated 4MB. What would happen is the operating system would reserve 4MB of address space. The operating system will try to keep the most recently/frequently accessed pieces of that 4MB in actual RAM. Any sections that are not frequently/recently accessed are copied to the "swap file". Now if the program touches a part of that 4MB that isn't actually in memory, the CPU will generate a "page fault". THe operating system will find some physical memory that hasn't been accessed recently and "page in" that page. It might have to write the content of that memory page out to the page file before it can page in the data being accessed. THis is why it is called a swap file - typically, when it reads something in from the swap file, it probably has to write something out first, effectively swapping something in memory with something on disk.
Typical MMU (memory management unit) hardware keeps track of what addresses are accessed (i.e. read), and modified (i.e. written). Typical paging implementations will often leave the data on disk when it is paged in. This allows it to "discard" a page if it hasn't been modified, avoiding writing out the page when swapping. Typical operating systems will periodically scan the page tables and keep some kind of data structure that allows it to intelligently and quickly choose what piece of physical memory has not been modified, and over time builds up information about what parts of memory change often and what parts don't.
Typical operating systems will often gently page out pages that don't change often (gently because they don't want to generate too much disk I/O which would interfere with your actual work). This allows it to instantly discard a page when a swapping operation needs memory.
Typical operating systems will try to use all the "unused" memory space to "cache" (keep a copy of) pieces of files that are accessed. Memory is thousands of times faster than disk, so if something gets read often, having it in RAM is drastically faster. Typically, a virtual memory implementation will be coupled with this "disk cache" as a source of memory that can be quickly reclaimed for a swapping operation.
Writing an effective virtual memory manager is extremely difficult. It needs to dynamically adapt to changing needs.
Typical virtual memory implementations feel awfully slow. When a machine starts to use far more memory that it has RAM, overall performance gets really, really bad.