Memory Caches
一、 内存的使用策略
1. 减少内存的开销
Slab cache
2. 减少系统服务时间的方法
l 文件系统的元数据(Filesystem metadata):buffer cache(slab cache)
l Disk IO:page cache
l IPC(Interprocess communication):shared momory(共享内存)
l Netwok IO:buffer cache、arp cache、connection track
3. 内存调优的注意事项
l 尽量回收页面内存,以避免内存的压力
l 内存调优对小的写操作不会很明显,内存调优主要是针对大量的写
二、 内存调优
1. Tuning page allocation
l 最小保留内存空间: vm.min_free_kbytes
[root@station9 ~]# sysctl -a|grep vm.min_free
vm.min_free_kbytes = 3831
#该内存空间将不会作为其他用途,减小特定程序的服务时间,会增加zone_normal的压力。
#有些应用程序进程会要使用大量内存,需要调节最小保留的内存空间以便满足此需求。
2. Tuning overcommit(过量使用):
l 过量使用:vm.overcommit_memory
[root@station9 ~]# sysctl -a|grep vm.overcommit_memory
vm.overcommit_memory = 0
#0=heuristic overcommit 关闭过量使用,有多少就分配多少。
#1=always overcommit 开启过量的使用,要多少分多少,不建议用该选项,大量过量使用可能会导致系统崩溃(内存溢出)。
#2=commit all swap plus a perentage of RAM (may be >100) 先利用所有的swap,同时将适量百度比的内存分配给应用程序。
l 过度使用百分比:vm.overcommit_ration
[root@station9 ~]# sysctl -a|grep vm.overcommit_ratio
vm.overcommit_ratio = 50
#该参数表示用于过度使用的内存百分比,与vm.overcommit_memory配合使用
l 测试:
[root@station9 ~]# watch -n 1 grep -i committed_as /proc/meminfo
Every 1.0s: grep -i committed_as /proc/meminfo Thu Aug 25 06:16:13 2011
Committed_AS: 192184 kB
#参看内存分配变化情况
[root@station9 ~]# vmemleak 1024 400
Process ID is: 2413
Grabbing some memory
Grabbing some memory
Grabbing some memory
#请求内存分配,每次1024KiB,请求400次,需安装软件包leaky-0.1-2.i386.rpm
3. Slab cache
Slab cache用于存放内核中频繁调用的小对象
l 查看slab cache信息
[root@station9 ~]# cat /proc/slabinfo
[root@station9 ~]# slabtop
[root@station9 ~]# vmstat –m
#slab只能查看,无法调slab存放的信息
4. Arp cache
Arp是Mac address映射IP address的条目表,存放在slab里的小对象。
l 查看arp cache
[root@station9 ~]#cat /proc/net/arp
[root@station9 ~]#ip neighbor list
l 清空arp cache
[root@station9 ~]#ip neighbor flush dev eth0
l 调整arp cache大小
[root@station9 ~]# sysctl -a|grep net.ipv4.neigh.default.gc_thresh
net.ipv4.neigh.default.gc_thresh3 = 1024
#硬限制,arp cache到1024条时,立即清空arp cache
net.ipv4.neigh.default.gc_thresh2 = 512
#软限制,arp cache达到128条时,默认每30s清空一次arp cache,到达512条时,每5s清空一次arp缓存
net.ipv4.neigh.default.gc_thresh1 = 128
#arp cache小于128条时不会清空arp cache
l 调整arp cache清空周期
[root@station9 ~]# sysctl -a|grep net.ipv4.neigh.default.gc_interval
net.ipv4.neigh.default.gc_interval = 30
#调整arp cache清空周期,默认30s
5. Page cache
l 作用
对IO有大量请求,且大部分请求是一样的,就会用到page cache:
File reads:默认每个文件读都需要将数据从磁盘读到内存,将这些数据放在page cache
Page cahe总是会检查IO的请求:
目录读、读写常规文件、读写磁盘块设备、访问内存映射文件、访问swap输出页等。
页总会分配一些文件数据给page cache。
l 查看page cache
#cat /proc/meminfo |grep -i page
[root@station9 ~]# cat /proc/meminfo |grep -i page
AnonPages: 67488 kB
PageTables: 2316 kB
HugePages_Total: 20
HugePages_Free: 20
HugePages_Rsvd: 0
Hugepagesize: 2048 kB #分配page cache 2M
l 调内存中保留作为page cache的内存大小
vm.lowmem_reserve_ratio
[root@station9 ~]# sysctl -a|grep lowmem
vm.lowmem_reserve_ratio = 256 256 32
#三个值分别代表 DMA Normal HighMem,在常规区域中将保留 256 页(默认)。
vm.vfs_cache_pressure
[root@station9 ~]# sysctl -a|grep vfs
vm.vfs_cache_pressure = 100
#内核回收用于page cache的倾向;缺省值100表示内核将把pagecachee保持在一个合理的百分比;降低该值低于100,将导致内核倾向于保留pagecache;增加该值超过100,将导致内核倾向于回收.
l 调到达率和丢失率
vm.page.cluster
[root@station9 ~]# sysctl -a |grep vm.page.cluster
vm.page-cluster = 3
#一次性性从swap往内存写的页数,2的3次方
vm.zone_reclaim_mode
[root@station9 ~]#echo “vm.zone_reclaim_mode = 1”>>/etc/sysctl.conf
#值0或1,当内存发生危机时是否尽量回收内存,0不回收,1回收,默认无此参数。仅支持X86_64。
6. Anonymouns pages
这些页属于某个进程,但是没有任何磁盘文件和它们有关。如阵列的数据等,进程间通信(IPC)的内存。anonymous pages可转换到swap里。
l 查看
#grep -i anon /proc/meminfo 或
#cat /proc/PID/statm
[root@station9 ~]# cat /proc/meminfo |grep -i anon
AnonPages: 67476 kB
三、 SysV IPC(Inter-Process Communication)
1. IPC主要手段:信号量、共享内存、消息队列。另外还有:管道、Socket等。非网络IPC和网络IPC(Socket API)都是需要的。
IPC按形式上分可分成4种不同的IPC形式:
1) 消息传递(管道、FIFO命名管道、消息队列)
2) 同步(互斥量、条件变量、读写锁、文件和记录锁、信号量):
信号量,是一个特殊变量,只能对它进行初始化操作、PV操作、删除操作。主要是PV操作(又称wait、signal或者up、down)。
3) 共享内存(匿名的和具名的)
Ø 共享内存是进程间最快速的通信方式:
Ø 进程共享同一块内存空间。
Ø 访问共享内存和访问私有内存一样快。
Ø 不需要系统调用和内核入口。
Ø 不造成不必要的内存复制
4) 远过程调用(Solaris门和SunRPC)
2. 查看IPC
#ipcs
[root@station9 ~]# ipcs
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x740003f9 1671168 root 600 4 0
0x740003ce 2392065 root 600 4 0
0x00000000 2785282 gdm 600 393216 2 dest
0x74000435 819203 root 600 4 0
0x740003cd 2359300 root 600 4 0
------ Semaphore Arrays --------
key semid owner perms nsems
------ Message Queues --------
key msqid owner perms used-bytes messages
[root@station9 ~]# df -h |grep shm
tmpfs 2.0G 0 2.0G 0% /dev/shm #共享内存大小
[root@station9 ~]# dd if=/dev/zero of=/dev/shm/test bs=1M count=50
50+0 records in
50+0 records out
52428800 bytes (52 MB) copied, 0.0626032 seconds, 837 MB/s
#直接写入数据到共享内存,/dev/shm中数据存放在共享内存中,而不是硬盘中,系统重启即丢失
3. tuning sysV IPC
l 修改内核信号量
kernel.sem
[root@station9 ~]# sysctl -a|grep kernel.sem
kernel.sem = 250 32000 32 128
#第一列,表示每个信号集中的最大信号量数目。
第二列,表示系统范围内的最大信号量总数目。
第三列,表示每个信号发生时的最大系统操作数目。
第四列,表示系统范围内的最大信号集总数目。
所以,(第一列)*(第四列)=(第二列)
l 修改消息队列的大小和数量
[root@station9 ~]# sysctl -a|grep kernel.msgm
kernel.msgmnb = 65536 #消息队列的最大长度(bytes)
kernel.msgmni = 16 #消息队列标识的最大数目,即系统范围内最大多少个消息队列
kernel.msgmax = 65536 #从一个进程发送到另一个进程的消息的最大长度(bytes)。进程间的消息传递是在内核的内存中进行的,不会交换到磁盘上,所以如果增加该值,则将增加操作系统所使用的内存数量。
l 修改共享内存大小
[root@station9 ~]# sysctl -a|grep kernel.shm
kernel.shmmni = 4096 #用于整个系统的共享内存段的最大数目(个)
kernel.shmall = 268435456 #系统上可以使用的共享内存的总量(bytes)
kernel.shmmax = 4294967295 #内核所允许的最大共享内存段的大小(bytes);实际可用最大共享内存段大小=shmmax * 98%,其中大约2%用于共享内存结构
4. 内存的剩余空间
[root@station9 ~]# free -ltm
total used free shared buffers cached
Mem: 4054 1040 3013 0 224 630
Low: 854 293 561
High: 3199 747 2452
-/+ buffers/cache: 186 3868
Swap: 8189 0 8189
Total: 12243 1040 11203
已经使用内存空间=used -buffers-cached
1040 -224-630 =186
剩余内存空间=free+buffers+cached
3013+224 +630 =3867
5、查看内存的使用情况
l system memory:
/proc/meminfo
/proc/zoneinfo
l page tables:
/proc/vmstat
l summary
vmstat -s
l io devices
/proc/iomem