点击上方【蓝字】关注博主
“ 深入探讨了内存的本质、虚拟内存与物理内存的映射关系,并详细阐述了 Buffer 和 Cache 在内存优化中的重要作用。通过了解这些概念,我们可以更清晰地理解系统资源的分配和利用方式,从而更好地掌控系统性能。”
内存是什么?
内存直接影响着程序运行的效率和系统稳定性。我们常说的“内存”通常是指虚拟内存,而操作系统实际使用的则是物理内存。
虚拟内存:虚拟内存是操作系统为每个进程创建的一个独立的、连续的地址空间,它允许进程访问比物理内存更大的内存范围。每个进程都认为自己拥有了完整的虚拟内存空间,但实际上,这只是一层抽象。历史上,在虚拟内存尚未引入之前,程序使用的都是物理地址,因此其寻址空间受到CPU地址线条数的限制。例如,在32位平台下,寻址的范围是
内存资源竞争:如果每个进程都被分配4GB的物理内存,当多个进程同时需要执行时,物理内存显然不够用。此时,未获得内存资源的进程只能等待,这会导致系统效率低下,频繁的内存装入和剔除操作更是增加了开销。
安全性问题:程序直接访问物理内存的方式,意味着一个进程可能会修改其他进程的数据,甚至改写内核空间的数据,这是不安全的。
地址分配混乱:由于内存是随机分配的,不同进程的地址空间可能不一致,导致程序运行的地址不正确。
物理内存:物理内存则是计算机硬件中实际存在的内存芯片,它的容量是有限的。操作系统会将多个进程的虚拟内存映射到物理内存上,并使用页表来记录虚拟地址和物理地址之间的对应关系。
虚拟内存与物理内存之间的关系:
映射关系:操作系统通过页表将虚拟内存空间映射到物理内存空间。页表类似于一个字典,将虚拟地址作为键,物理地址作为值。
按需分配:进程在运行时并不会立即将所有虚拟内存空间映射到物理内存,而是根据需要进行分配,即按需分页。当进程访问一个从未被分配物理内存的地址时,就会触发缺页异常。
页面置换: 当物理内存空间不足时,操作系统会使用页面置换算法选择一个页,将其从物理内存中移出,并将其交换到磁盘上,释放出空间。
虚拟内存和物理内存示意图:
虚拟内存的优势:
每个进程都被虚拟分配4GB的地址空间,多个进程共享物理内存,提高了内存利用率,减少了内存浪费。
每个进程拥有独立的虚拟内存空间,可以有效隔离进程,防止一个进程访问另一个进程的内存空间,增强了系统安全。
虚拟内存允许程序访问比物理内存更大的内存空间,可以运行更大更复杂的程序。
当进程尝试访问某个地址时,必经如下步骤:
地址转换:进程首先需要将虚拟地址转换为实际的物理地址。
内存共享:所有进程共享物理内存,且每个进程仅映射其所需的虚拟地址空间。
页表管理:进程需了解哪些虚拟地址已映射到物理内存,哪些未映射(可能位于磁盘),以及在物理内存中的具体位置,通常通过页表进行管理。
页表结构:页表中的每一条记录分为两部分,第一部分指示该页是否在物理内存中,第二部分则给出物理地址(若在的话)。
缺页异常:当进程访问虚拟地址时,若页表显示该页不在物理内存,则会触发缺页异常。
处理缺页异常:操作系统会立即阻塞该进程,并从硬盘将对应页调入内存。若物理内存已满,则需依据操作系统的页面置换算法决定覆盖哪一页。
当进程访问一个不在物理内存中的虚拟地址时,就会触发缺页异常。操作系统会执行以下步骤来处理缺页异常:
检查页表:操作系统会检查页表,发现对应的页面不在物理内存中。
选择页面:操作系统会根据页面置换算法选择一个页面,将其从物理内存中移出,并将内容写入磁盘。
加载页面:操作系统会从磁盘中读取需要访问的页面,并将它加载到物理内存中。
更新页表:操作系统会更新页表,将新加载的页面地址记录到页表中。
恢复进程:操作系统会恢复被阻塞的进程,使其继续运行。
页表工作原理示意图:
CPU 想访问虚拟地址所在的虚拟页(VP3)。
根据页表,找出页表中第三条的值,判断有效位。
如果有效位为 1,代表该页面在物理内存中,根据物理页号找到对应的物理页面,获取数据。
如果有效位为 0,代表该页面不在物理内存中,触发缺页异常,调用内核缺页异常处理程序。
内核选择一个页面作为被覆盖的页面,将该页面的内容写入磁盘。
将 VP3 映射的磁盘文件缓存到被选择的物理页面上。
更新页表,将有效位设置为 1,并将物理页号写入页表。
缺页异常处理完毕后,返回中断前的指令,重新执行,此时缓存命中。
将找到的内容映射到高速缓存中,CPU 从高速缓存中获取该值,结束。
示例,假设一个进程需要访问虚拟地址0x1000,而该地址对应的物理内存页尚未加载到物理内存中:
CPU 发出访问0x1000的请求。
操作系统检查页表,发现0x1000对应的页面不在物理内存中,而是位于磁盘上的某个位置。
操作系统选择一个物理内存页面,将它写入磁盘。
操作系统从磁盘读取0x1000对应的页面,并将其加载到物理内存中。
操作系统更新页表,将0x1000对应的物理页面地址记录到页表中。
CPU 再次访问0x1000时,会命中缓存,直接从物理内存中获取数据。
进程创建与内存映射:当进程创建时,内核为其分配4GB的虚拟内存。此时,内存仅是一个布局尚未实际装入数据,映射关系已建立,但数据和代码(如.text .data段)仍保留在硬盘上。只有当进程实际访问时,发生缺页异常,才会将数据复制到物理内存中。
在进程动态分配内存(使用malloc)时,同样只是在虚拟内存中划分空间,页表项的设置也只是虚拟内存的管理,只有当进程实际访问该内存时,才会触发缺页异常。
虚拟内存是操作系统的一种重要的内存管理机制,它为每个进程提供了独立的地址空间,并通过页表将虚拟地址映射到物理地址,实现了内存共享和保护,提高了内存利用率,为现代操作系统提供了高效可靠的内存管理能力。
除了按需分页,操作系统还可能使用预读技术,提前将磁盘上的页面加载到物理内存中,以减少缺页异常的发生频率。页表本身也存储在物理内存中,操作系统会使用多级页表来管理虚拟内存空间,以节省内存空间。
内存中的 buffer 和 cache
root@ubuntu:/home/root# free -h
total used free shared buff/cache available
Mem: 5.9G 1.2G 1.1G 36M 3.6G 4.3G
Swap: 974M 12K 974M
该界面展示了物理内存(Mem)与交换分区(Swap)使用情况的详细信息,包括总内存、已用内存、缓存区、可用内存等关键参数。在这里,缓存是由 Buffer 和 Cache 两部分组成的总和。
Mem 行(第二行)是内存的使用情况。涵盖了物业内存总量、已使用量与可用量。
Swap 行(第三行)是交换空间的使用情况,反映了系统在物理内存不足时如何借助虚拟内存来进行数据存储。
total 列显示系统总的可用物理内存和交换空间大小。表明资源的整体可用性。
used 列显示已经被使用的物理内存和交换空间,帮助用户了解当前内存的实际使用情况。
free 列显示还有多少物理内存和交换空间可用使用,从而为应用程序的运行提供参考。
shared 列显示被共享使用的物理内存大小,反映了多个进程间共享数据的程度。
buff/cache 列显示被 buffer 和 cache 使用的物理内存大小。当系统启动或平时运行时,这部分内存会被作为缓存使用,以提高性能。
available 列显示还可以被应用程序使用的物理内存大小。
对于buffer和cache的区别:
Buffers 是对原始磁盘块的临时存储,也就是用来缓存磁盘的数据,通常不会特别大(20MB 左右)。这样,内核就可以把分散的写集中起来,统一优化磁盘的写入,比如可以把多次小的写合并成单次大的写等等。
Cached 是从磁盘读取文件的页缓存,也就是用来缓存从文件读取的数据。这样,下次访问这些文件数据时,就可以直接从内存中快速获取,而不需要再次访问缓慢的磁盘。
Buffer 既可以用作“将要写入磁盘数据的缓存”,也可以用作“从磁盘读取数据的缓存”。
Cache 既可以用作“从文件读取数据的页缓存”,也可以用作“写文件的页缓存”。
Buffer 主要是针对磁盘数据进行的缓存,而 Cache 则是针对文件数据进行的缓存。它们在内存管理中各自扮演着重要的角色,既可以用于读请求,也可以用于写请求。
在读写普通文件的过程中,所有操作都经过文件系统,这个系统负责与物理磁盘之间的交互;然而,在进行对磁盘或分区的读写操作时,通常会跳过文件系统层,这被称为“裸I/O”。这两种读写方式在缓存使用上是有所区别的,正是本文讨论的 Buffer 和 Cache 的重要性所在。通过理解这两者之间的差异,可以更好地优化系统性能,确保数据存取的高效与准确。
内存优化监测
Buffer 和 Cache 分别用于缓存对磁盘和文件系统的读写数据。
从写的角度来看,内存的优化不仅可以有效地提升磁盘和文件的写入效率,还能为应用程序带来实质性的好处。当数据被写入 Buffer 后,应用程序可以迅速返回去继续执行其他工作,而不必等待数据真正落到磁盘上。这一机制极大地提高了系统的响应速度,使得应用程序能够保持良好的用户体验,尤其在处理大量数据时,能够显著缩短工作延迟。同时,系统会在适当时机将这些数据从 Buffer 中写入磁盘,确保数据的持久性与安全性。
从读的角度来看,优秀的内存管理优化能够显著提高那些频繁访问数据的读取速度。当数据经过 Cache 存储后,下次读取时便可以直接从内存中快速提取,相比之下,这种方式无疑要比每次都访问较慢的磁盘来的高效得多。通过降低磁盘的随机 I/O 操作频率,内存优化还能够有效减轻对磁盘的压力。这种减轻压力的效果不仅延长了磁盘的使用寿命,同时也提升了系统整体的稳定性,进一步优化了系统性能。
因此,内存的优化与监测不是一项单一的任务,而是一系列复杂操作的结合,涉及对 Buffer 和 Cache 有效利用,以最大化性能和资源利用率。通过持续的监测和调整,确保系统在读写操作过程中始终能够保持高效和稳定。这种优化过程不仅适用于大型应用程序,也惠及日常使用场景,为用户带来更流畅的体验。
一些用于监测Linux内存的方法和工具:
free:这个命令提供了系统内存的使用情况,包括总内存、已用内存、空闲内存、缓存和交换内存等信息。
free -h
top/htop:这两个命令可以监测系统的性能,包括内存和CPU的使用情况。htop提供了更友好的界面。
vmstat:这个命令显示了关于虚拟内存、进程、CPU活动等的统计信息。
vmstat 1
sar:通过sysstat工具包提供了系统资源的收集和报告功能,可以监测内存、CPU、IO等。
sar -r 1
总结
虚拟内存是操作系统为每个进程提供的独立地址空间,通过页表将虚拟地址映射到物理地址,实现了内存共享和保护,提高了内存利用率。
物理内存则是计算机硬件中实际存在的内存芯片,其容量是有限的。
Buffer是针对磁盘数据进行的缓存,可以用于优化磁盘读写操作,提高效率和稳定性。
Cache是针对文件数据进行的缓存,可以提高文件访问速度,降低磁盘的随机 I/O 操作频率。
内存监测工具如 free、top、htop、vmstat 和 sar 可以帮助我们监控系统内存的使用情况,及时发现并解决潜在问题。
公众号: Lion 莱恩呀
微信号: 关注获取
扫码关注 了解更多内容
点个 在看 你最好看