以下示例列出了空闲内存为1G的Red Hat Linux系统的命令cat /proc/meminfo的输出: MemTotal: 24523256 kB MemFree: 1031252 kB <—系统显示为free(空闲)的内存容量 MemAvailable: 8174892 kB Buffers: 8316 kB <—从磁盘都读出的数据的数据结构使用的内存容量 Cached: 16075816 kB <—缓存使用的内存容量 SwapCached: 552 kB Active: 15859172 kB Inactive: 5092080 kB Active(anon): 12188888 kB Inactive(anon): 2162424 kB Active(file): 3670284 kB Inactive(file): 2929656 kB Unevictable: 607892 kB Mlocked: 607896 kB SwapTotal: 16777212 kB SwapFree: 16714740 kB Dirty: 1656 kB <—脏数据使用的内存容量 Writeback: 0 kB AnonPages: 5474420 kB Mapped: 5432692 kB Shmem: 9349052 kB Slab: 872632 kB <—内核使用的内存容量 SReclaimable: 723244 kB SUnreclaim: 149388 kB KernelStack: 20416 kB PageTables: 509636 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 29038840 kB Committed_AS: 17713852 kB VmallocTotal: 34359738367 kB VmallocUsed: 258860 kB VmallocChunk: 34359341052 kB HardwareCorrupted: 0 kB AnonHugePages: 0 kB CmaTotal: 0 kB CmaFree: 0 kB HugePages_Total: 0 <—大页面保留的内存容量=HugePages_Total*Hugepagesize HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB DirectMap4k: 329664 kB DirectMap2M: 24836096 kB
1. 缓存(cache)和脏缓存页面(dirty cached pages)
Linux内核尝试通过拷贝磁盘上的数据到内存来加速访问和优化I/O性能。缓存(cache)使用的内存容量列出在/proc/meminfo的输出中(上面有标注)。如果因为其他原因需要更多的内存空间,缓存使用的内存容量可以快速地被释放。然而,缓存页面具有两种类型,可以收回的缓存使用的内存容量取决于多少缓存被视为脏缓存。
脏缓存页面包含着系统仍然需要写到磁盘的更改数据。不管系统什么时候需要回收内存,它都可以回收干净的缓存页面,但脏缓存页面必须先拷贝回磁盘。
如果系统有大量的频繁的写操作,脏缓存会占用很多的内存,系统将会变得更低效。可以设置系统的内核参数vm.dirty_backgroud_ratio来限制缓存的数据数量。该参数指定缓存页面占用系统内存总容量达到设置的百比分时,pdflush后台写回进程开始将脏数据从内存中写出,缺省值为10%。为了限制缓存页面占用内存的容量,可以减小该参数的值,让pdflush进程更早开始写出脏数据。
临时更改参数的命令(以下将参数设置为8%): # sysctl -w vm.dirty_background_ratio=8 如果需要永久更改参数,编辑/etc/sysctl.conf文件,加上以下行: vm.dirty_background_ratio = 8
2. 进程实际使用了多少内存
使用top或ps auxw命令可以看到进程使用的内存容量百分比。然而,进程实际使用的内存空间的情况会更复杂。
下图Figure 1从进程的角度说明了进程的地址空间,包含映射(mapped)和非映射区域(unmapped areas)。映射区域返回信息,但如果进行进程尝试访问非映射区域,它会遇到分段错误(segmentation fault)。 你可能会觉得映射区域与进程使用的内存直接相关。在这个例子中,它会解释为40k的内存空间(10个4k的页面)。然而,这不是事实的全部。
如下图Figure 2所示,场景背后有更多的进程涉及其中。 如上图所示,2个内存页面保存到了swap分区的磁盘上,1个内存页面是还没有缓存的空文件页,2个内存页面已分配内存但还没有使用(内存过量使用)。这个进程实际使用的内存页面为4(3个物理内存页面和1个缓存页面)。这是进程更准确的内存使用视图。
在Figure 2的下面是另外一个进程,它使用部分相同的页面。如果累计两个进程的VmRSS值,会得到总值为6,即使实际使用的页面为4(其中有两个页面是两个进程共享)。如果中止掉上面的那个进程,只会释放2个内存页面,因为另外1个进程保持着1个cache页面和1个物理内存页面。
3. 内核使用的内存
Linux内核使用的内存容量可以通过将/proc/meminfo输出中的slab,dirty和buffers三者的值累加起来获得。 buffers值反映了从磁盘读出的数据的结构信息的数量(不是文件的部分,而是指向实际文件的结构信息,例如ext4 inode信息)。 Linux内核使用的大部分内存列在slab值中。当内核从slab缓存中分配内存时,它会做标记,这样做的目的是将内核分配的内存记录在/proc/slabinfo中。
4. 保留的huge pages内存
huge pages特性让系统可以提供比普通的4K页面更大的页面选择,在数据库服务器中配置可以提高内存性能。大页面保留的内存容量等于/proc/meminfo输出中的HugePages_Total*Hugepagesize,详情可参考另外一篇文章Redhat 5.8 Huge Pages参数设置错误导致的内存不足(Out of memory)故障记录。
5. 当还有缓存页面可用时为什么内核还要使用swap?
当内核将页面交换到swap分区时,页面停留在swap分区直到再次被使用。这就意味着如果内存使用出现突然的峰值时,页面被交换到swap分区,这些页面不会在内存出现空闲时马上交换回内存。这些页面要在应用程序尝试访问它们时才会再交换回内存。
另外,通过vm.swappiness可以设置剩余多少物理内存(百分比)时使用虚拟内存,该值默认值为30,根据需要使用上面的方法进行参数vm.swappiness的设置。 # cat /proc/sys/vm/swappiness 30
参考来源:《Analyzing Memory Usage in Red Hat Enterprise Linux,Allison Pranger》
|