MMU页表的内存消耗
要使用MMU,是需要代价的:内存、系统功耗、开发复杂度等各方面体现出来。我这里来扯一下内存的代价。
ARM系统可以有两种虚拟地址分段方式,有2段的和3段的。2段的分法是以1MB作为页(此时也叫Section),而3段的分法中,其页面大小可以是1KB、4KB、64KB。下面我们以4KB讨论吧。
4KB页的地址转换过程中,把虚拟地址分为3段,每段的bit数为分别是:12bits、8bits、12bits(共32bits)。
大家都知道,每个进程都拥有独立的页表(除了同一进程内的线程,linux通常不区分进程与线程的概念)。也就是说,整个系统中用作页表的物理内存等于所有进程的页表所占物理内存的总合。那么每个进程最多会占用多少物理内存用作页表呢?理论上,每个进程可以访问4GB地址空间,如果该进程随时可能访问到4GB空间的任何地址,那么页表就应该全部留在内存中。以此计算的话,该进程在页表上消耗的内存为:16KB(转换表)+4096*1KB(粗页表)=4112KB。这样的话,系统中如果有几十个进程的话,内存消耗是很可怕的!
但是,这是理论上的讨论罢了。事实上每个进程不会有4GB的访问空间,操作系统往往把地址空间分为好几块,比如Linux把低端的3GB内存空间用于应用程序进程(叫做用户空间),而高端1GB空间留给操作系统自己(叫做系统空间)。这样,每个进程都共享高端内核空间的页表,内存消耗就大大减少了!此外,页表所需要的内存不是在进程加载的时候就全部分配的,而是在缺页异常发生的时候,才由操作系统分配并填充配置。因此,实际上用于某进程的页表内存视该进程所访问的内存空间跨度而定。
呵呵,说来说去好像是废话一样,但是,这些废话会让人明白一个事实:在虚拟地址转换到物理地址的过程中,需要由硬件来完成一系列查表行为,而这些页表都是要消耗内存的!通过以上记录,巩固了MMU的知识。