2-PageCachechan产生释放及优化( 七 )


从应用代码层面来优化; 从系统层面来调整
代码层优化
从应用程序代码层面来解决是相对比较彻底的方案,因为应用更清楚哪些 Page Cache 是重要的,哪些是不重要的,所以就可以明确地来对读写文件过程中产生的 Page Cache 区别对待 。
比如说,对于重要的数据,可以通过 mlock(2) 来保护它,防止被回收以及被drop;对于不重要的数据(比如日志),那可以*通过 (2) *告诉内核来立即释放这些 Page Cache 。
mlock(2) 来保护重要数据防止被回收或者被 drop 的例子
#include #include #include #include #include #include #define FILE_NAME "/home/yafang/test/mmap/data"#define SIZE (1024*1000*1000)int main(){int fd;char *p;int ret;fd = open(FILE_NAME, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);if (fd < 0)return -1;/* Set size of this file */ret = ftruncate(fd, SIZE);if (ret < 0)return -1;/* The current offset is 0, so we don't need to reset the offset. *//* lseek(fd, 0, SEEK_CUR); *//* Mmap virtual memory */p = mmap(0, SIZE, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, 0);if (!p)return -1;/* Alloc physical memory */memset(p, 1, SIZE);/* Lock these memory to prevent from being reclaimed */mlock(p, SIZE);/* Wait until we kill it specifically */while (1) {sleep(10);} /**Unmap the memory.* Actually the kernel will unmap it automatically after the* process exits, whatever we call munamp() specifically or not.*/munmap(p, SIZE);return 0;}
通过 mlock(2) 来锁住了读这个文件内容对应的。在运行上述程序之后,我们来看下该如何来观察这种行为:确认这些 Page Cache是否被保护住了,被保护了多大 。这同样可以通过 /proc/ 来观察:
$ egrep "Unevictable|Mlocked" /proc/meminfoUnevictable: 1000000 kBMlocked: 1000000 kB
系统层优化
修改源码是件比较麻烦的事,如果可以不修改源码来达到目的那就最好不过了 。Linux 内核同样实现了这种不改应用程序的源码而从系统层面调整来保护重要数据的机制,这个机制就是
它大致的思路是,将需要保护的应用程序使用来保护起来,这样该应用程序读写文件过程中所产生的 Page Cache 就会被保护起来不被回收或者最后被回收 。大致的原理如下图所示:
提供了几个内存水位控制线 .{min, low, high,max}。
.max
这是指内的进程最多能够分配的内存,如果不设置的话,就默认不做内存大小的限制
.high
如果设置了这一项,当内进程的内存使用量超过了该值后就会立即被 回收掉,所以这一项的目的是为了尽快的回收掉不活跃的 Page Cache
.low
这一项是用来保护重要数据的,当内进程的内存使用量低于了该值后,在内存紧张触发回收后就会先去回收不属于该的 Page Cache,等到其他的 Page Cache 都被回收掉后再来回收这些 Page Cache 。
.min
这一项同样是用来保护重要数据的,只不过与 memoy.low 有所不同的是,当内进程的内存使用量低于该值后,即使其他不在该内的Page Cache 都被回收完了也不会去回收这些 Page Cache,可以理解为这是用来保护最高优先级的数据的 。
【2-PageCachechan产生释放及优化】如果你想要保护你的 Page Cache 不被回收,你就可以考虑将你的业务进程放在一个中,然后设置 .{min,low} 来进行保护;与之相反,如果你想要尽快释放你的 Page Cache,那你可以考虑设置 .high 来及时的释放掉不活跃的 Page Cache 。