我在此处粘贴一些代码,这些代码使用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(来自顶部命令)不断增加,直到14GB。我的印象是,当我映射文件时,VIRT将增加而不是RES。那么当我们写入mmap文件时,是先将其写入内存,然后再提交到磁盘吗?还是使用了任何中间缓冲区/缓存?
在“ free”命令的帮助下,我还观察到内存使用量达到16GB之后,便会使用缓冲区。以下是上述代码执行时不同时间的free命令的一些快照:
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的使用。但这似乎不起作用。希望将所有数据保留在内存映射文件中,并在需要时将其读回。
我使用的内存映射不正确吗?还是它的行为方式?
只要有足够的可用内存,就会发生这种情况,然后操作系统开始从保留集中清除LRU页面(除非它们被VirtualLock/ mlocked或否则无法移动(如内核页面,DMA缓冲区,安全敏感数据等)。
VirtualLock
mlock
因此,操作系统乐观地将页面保留得尽可能长(只要没有其他进程争用内存,这就会提高性能)。
这表示操作系统正在执行其工作。
您正在写入磁盘。磁盘访问比内存访问慢很多。实际将数据写到磁盘的频率取决于调整。此答案列出了Linux(您似乎正在使用)上可用的一些调整参数