平常工作中,发现有蛮多日常细节与内存管理有关,一直想要停下来总结总结,未果。这两天和一朋友沟通时,虚拟地址与物理地址的mapping方式这个问题,让平常一直考虑的关于top、mmap、ringbuffer、DirectByteBuffer等细节点在脑海中翻腾,竟然一时语塞。所以今天在家写了点测试代码,让自己把思路理顺,整理出来,希望这些基础知识对大家有用。
1.硬件和物理内存
物理内存概要
大家都知道,物理内存就是RAM。处理器通过内存总线连接到物理内存,总线位数(比如32位或者48位)决定了可寻址的物理内存大小。这里提到48位这个值,是提醒不要与CPU的寄存器带宽混淆。X86_64的寄存器带宽是64,但是物理地址位数可能是48。(物理地址扩展后,物理地址位数也可能大于寄存器带宽)。
现在总线位数很大的情况下,只有物理地址受限了(物理地址主要受限于插槽的数量和成本)。物理内存分页寻址,每页4K。对于32位的地址,第0页从0x00000000到0x00001000。可以看到,只需要前20位用来寻址物理页,而后12位用来标示页内地址。
思考一:这样内存分页使用有什么优点呢?在本文最后讲到ringbuffer时会分析这个问题。
物理内存和磁盘的互惠交易
在linux协调下,物理内存和磁盘间有“最惠国待遇条约”:
1) 物理内存充裕时:
linux会把一些物理内存用于io的buffer及cache,提升系统运行效率。
Linux下的sar -r命令结果中,总体可用的物理内存应该为:kbm