我在这里粘贴一些代码,它使用boost iostream来mmap&然后写入映射文件:
typedef unordered_map<int, string> work;
int main()
{
work d;
d[0] = "a";
boost::iostreams::mapped_file_params params;
params.path = "map.dat";
params.new_file_size = 1000000000;
params.mode = (std::ios_base::out | std::ios_base::in);
boost::iostreams::mapped_file mf;
mf.open(params);
work* w = static_cast<work*>((void*)mf.data());
w[0] = d;
for(int i=1; i <1000000000 ;++i)
{
w->insert(std::make_pair(i, "abcdef"));
}
mf.close();
}
当我在带有8个处理器和16GB RAM的centos 6盒子上执行此操作时,我观察了以下内容:
当数据被插入到内存映射文件中时,RES(来自top命令)不断增加,达到14GB。 我的印象是,当我mmap文件时,VIRT会增加而不是RES。 那么当我们写入mmap文件时,首先将其写入内存然后提交给磁盘?或者是否使用了中间缓冲区/缓存?
在&#34; free&#34;的帮助下命令,我还观察到在内存使用量达到16GB后,使用了缓冲区。以下是上述代码执行时不同时间的自由命令快照:
total used free shared buffers cached
Mem: 16334688 10530380 5804308 0 232576 9205532
-/+ buffers/cache: 1092272 15242416
Swap: 18579448 348020 18231428
total used free shared buffers cached
Mem: 16334688 13594208 2740480 0 232608 9205800
-/+ buffers/cache: 4155800 12178888
Swap: 18579448 348020 18231428
total used free shared buffers cached
Mem: 16334688 15385944 948744 0 232648 9205808
-/+ buffers/cache: 5947488 10387200
Swap: 18579448 348020 18231428
total used free shared buffers cached
Mem: 16334688 16160368 174320 0 204940 4049224
-/+ buffers/cache: 11906204 4428484
Swap: 18579448 338092 18241356
total used free shared buffers cached
Mem: 16334688 16155160 179528 0 141584 2397820
-/+ buffers/cache: 13615756 2718932
Swap: 18579448 338092 18241356
total used free shared buffers cached
Mem: 16334688 16195960 138728 0 5440 17556
-/+ buffers/cache: 16172964 161724
Swap: 18579448 572052 18007396
这种行为意味着什么?
与写入内存相比,将数据写入内存映射文件需要花费大量时间。这是什么原因?
我希望在处理大量数据时使用内存映射来降低RES使用率。但它似乎没有这样的方式。希望将所有数据保存在内存映射文件中,并在需要时将其读回。
我是否错误地使用了内存映射?或者说它的行为方式是什么?
答案 0 :(得分:2)
VIRT将立即增加(所有页面映射进入进程地址空间)。当页面使用时,RES将增加,这会导致它们被分页到物理内存中。
只要有足够的可用内存,操作系统就会开始从保留的集合中清除LRU页面(除非它们是VirtualLock
/ mlock
- 或者不可移动(如内核页面,DMA缓冲区,安全敏感数据等。)。
因此,操作系统乐观地保留尽可能长的页面保留(只要没有其他进程争用内存,就可以提高性能)。
这表示操作系统正在完成它的工作。
您正在写入磁盘。磁盘访问(很多)比内存访问慢。数据实际写入磁盘的频率取决于调优。这个答案列出了linux上可用的一些调优参数(您似乎正在使用它):