Linuxオペレーティングシステムファイルキャッシュの解放
http://pthread.blog.163.com/blog/static/1693081782011111402639863/
仕事をして以来、この技術ブログを更新したことがありません.仕事をしても書くことがないし、忙しいのは確かだ.最近少し暇なので、とりあえず開けて書いておきましょう.
会社で新人の練習問題をする時、テーマはネットとローカルを通じてそれぞれ1つの約12 Gの大きいファイルを読み取って、そこから各行を読み取って、各行の特定のいくつかのフィールドに対して、分詞庫の分詞を呼び出してそして語の周波数を統計します.当時、12 Gのファイルを1回読み込んだ後、システムにキャッシュがあるのが憂鬱だった.そして2回目の再稼働の際、キャッシュの影響で性能差が大きかった(ローカル読み取りではほぼ3倍の性能差があった).しかし当時の開発機器では、自分は一般ユーザー権限しかなく、/proc/sys/vm/drop_cacheを修正することで目的を達成することができなかったため、結局この問題は解決しなかった.
その後、Linuxのシステム呼び出しが見つかりました.
#include
int posix_fadvise(int fd, off_t offset, off_t len, int advice);
POSIX_FADV_DONTNEEDのオプションがあります.ネットで探してみると、多くの人がこの問題に遭遇しているようなので、私の解決策をここに置いておきました.そこで、小さなツールを書いて、システム内のファイルのキャッシュを一括クリアしました.
#define _FILE_OFFSET_BITS 64
#define __USE_XOPEN2K
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <getopt.h>
const struct option dcache_options[] = {
{"sync",0,NULL,'s'},
{"help",0,NULL,'h'},
{NULL,0,NULL,0}
};
void usage(char* proc_name,int exit_code)
{
printf("dcache is an utility to drop file cache.
"
"usage:%s [-s] file
"
"\t-s,--sync, sync data before drop cache.
"
"\t-h,--help, print help.
",proc_name);
exit(exit_code);
}
int dcache(int fd, int sync_data)
{
off_t off,len;
struct stat buf;
int save_errno;
save_errno = errno;
if (sync_data) {
if (fsync(fd) < 0) {
printf("%s
",strerror(errno));
errno = save_errno;
return -1;
}
}
if (fstat(fd,&buf) < 0) {
printf("%s
",strerror(errno));
errno = save_errno;
return -1;
}
off = 0;
len = buf.st_size;
if (posix_fadvise(fd,off,len,POSIX_FADV_DONTNEED) < 0) {
printf("%s
",strerror(errno));
errno = save_errno;
return -1;
}
return 0;
}
int main(int argc, char* argv[])
{
int c,fd;
char* file;
int long_index = 0;
int print_help = 0;
int sync_data = 0;
while ((c = getopt_long(argc,argv,"sh",dcache_options,&long_index)) != -1) {
switch (c) {
case 's':
sync_data = 1;
break;
case 'h':
print_help = 1;
break;
default:
printf("unknown option -%c
",c);
usage(argv[0],EXIT_FAILURE);
break;
}
}
if (print_help) {
usage(argv[0],EXIT_SUCCESS);
}
if (optind >= argc) {
printf("file name required
");
exit(EXIT_FAILURE);
}
for (c = optind; c < argc; ++c) {
file = argv[c];
if ((fd = open(file,O_RDWR)) < 0) {
printf("open %s failed.
",file);
} else {
printf("drop cache of %s %s.
",file,dcache(fd,sync_data) == 0?"success":"failed");
close(fd);
}
}
exit(EXIT_SUCCESS);
}
使用方法:dcache -h
dcache is an utility to drop file cache.
usage:dcache [-s] file
-s,--sync, sync data before drop cache.
-h,--help, print help.
--syncオプションは、ハードディスク(HDD)にデータを書き込むために使用されます.man posix_fadviseが次のように述べているからです.
POSIX_FADV_DONTNEED attempts to free cached pages associated with the specified region. This is useful, for example, whilestreaming large files. A program may periodically request the kernel to free cached data that has already been used, so that more useful cached pages are not discarded instead.
Pages that have not yet been written out will be unaffected, so if the application wishes to guarantee that pages will be
released,
it should call fsync(2) or fdatasync(2) first.
POSIX_FADV_DONTNEEDはcleanページのみを解放し、dirtyページはその影響を受けないので、ファイルを書いて--syncオプションを使わないと、汚れたページは解放されず、キャッシュも解放されません.だからdcacheを使うときは--syncオプションをいつ使うかをはっきりさせなければなりません.
会社の機械で実験をして、4 kw+行のテキストファイル、8 GBで実験をしました.
まずfree-m cached総数48345 Mを見てみましょう
total used free shared buffers cached
Mem: 64334 50469 13864 0 196 48345
それからwc-l 5 kw.txt、1回のファイルを読み取って、wc出力ファイルの行数は
44731963 5kw.txt
次にfree-mでメモリの状況をもう一度見ます.
total used free shared buffers cached
Mem: 64334 58802 5532 0 204 56670
これにより、cached pageは8325 M増加し、私たちのファイルサイズに近いことがわかります.その後、dcacheツールを使用してシステム内の対応するファイルのキャッシュを解放します.
dcache 5kw.txt
drop cache of plsi_index.5kw.txt success.
再びfree-mを使ってcachedがやはり8 GB解放されたのを見て、ツールが確かに役に立ったことを説明しました.
free -m
total used free shared buffers cached
Mem: 64334 50477 13856 0 204 48346