[英]After memory-mapping, the process still consumes physical memory when there is a cache
I'm trying to understand mmap
.我想了解mmap
。 As i know, mmap
should map virtual address to page cache & thus there is no need to copy data from page cache to a process's virtual memory, and eventually there is a single copy of data in the whole machine.据我所知, mmap
应该将 map 虚拟地址指向页面缓存,因此无需将数据从页面缓存复制到进程的虚拟 memory,最终整个机器中只有一个数据副本。
However, when I try to mmap
and read it, I can see the memory increases twice as file reading size, do I interpret it incorrectly or anything wrong about my code?但是,当我尝试mmap
并读取它时,我可以看到 memory 增加了文件读取大小的两倍,我对它的解释不正确还是我的代码有什么问题?
Memory consumption before testing: Memory 测试前消耗:
$ free -m
total used free shared buff/cache available
Mem: 3924 1391 2280 13 251 2292
Swap: 0 0 0
I run below python code:我在下面运行 python 代码:
import mmap
import os
import time
# file2.db is a 2 GB file
with open("/var/tmp/file2.db", "r") as f:
with mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ) as mm:
x= mm.read(500000000)
time.sleep(10000)
$ python3 mmap_read.py &
Memory consumption after testing: Memory 测试后消耗:
$ free -m
total used free shared buff/cache available
Mem: 3924 1703 1575 13 644 1980
Swap: 0 0 0
I further check syscall used by process, looks like there is no data copy我进一步检查进程使用的系统调用,看起来没有数据副本
$ sudo perf record python3 mmap_read.py & # record syscall
$ sudo perf report
Result结果
Samples: 128 of event 'cpu-clock:pppH', Event count (approx.): 1292929280
Overhead Command Shared Object Symbol
24.22% python3 [kernel.kallsyms] [k] do_user_addr_fault
4.69% python3 [kernel.kallsyms] [k] rmqueue
3.91% python3 [kernel.kallsyms] [k] __add_to_page_cache_locked
3.91% python3 [kernel.kallsyms] [k] charge_memcg
3.91% python3 libc.so.6 [.] 0x00000000001a0e81
3.12% python3 [kernel.kallsyms] [k] __lock_text_start
3.12% python3 [kernel.kallsyms] [k] xas_load
3.12% python3 libc.so.6 [.] 0x00000000001a0ef0
2.34% python3 [kernel.kallsyms] [k] __mod_lruvec_state
2.34% python3 [kernel.kallsyms] [k] do_anonymous_page
2.34% python3 [kernel.kallsyms] [k] free_unref_page_list
2.34% python3 [kernel.kallsyms] [k] release_pages
2.34% python3 libc.so.6 [.] 0x00000000001a0e6f
1.56% python3 [kernel.kallsyms] [k] __cgroup_throttle_swaprate
1.56% python3 [kernel.kallsyms] [k] __mod_node_page_state
1.56% python3 [kernel.kallsyms] [k] filemap_map_pages
1.56% python3 [kernel.kallsyms] [k] pmd_page_vaddr
1.56% python3 [kernel.kallsyms] [k] pmd_pfn
1.56% python3 [kernel.kallsyms] [k] xa_get_order
1.56% python3 libc.so.6 [.] 0x00000000001a0e4c
1.56% python3 libc.so.6 [.] 0x00000000001a0e7d
1.56% python3 libc.so.6 [.] 0x00000000001a0e86
1.56% python3 libc.so.6 [.] 0x00000000001a0f47
0.78% python3 [kernel.kallsyms] [k] __bio_add_page
0.78% python3 [kernel.kallsyms] [k] __handle_mm_fault
0.78% python3 [kernel.kallsyms] [k] __mem_cgroup_charge
0.78% python3 [kernel.kallsyms] [k] __page_set_anon_rmap
0.78% python3 [kernel.kallsyms] [k] arch_local_irq_enable
0.78% python3 [kernel.kallsyms] [k] blk_mq_dispatch_rq_list
0.78% python3 [kernel.kallsyms] [k] cgroup_rstat_updated
0.78% python3 [kernel.kallsyms] [k] clear_page_erms
0.78% python3 [kernel.kallsyms] [k] do_set_pte
0.78% python3 [kernel.kallsyms] [k] elv_rqhash_add
0.78% python3 [kernel.kallsyms] [k] finish_task_switch.isra.0
0.78% python3 [kernel.kallsyms] [k] get_mem_cgroup_from_mm
0.78% python3 [kernel.kallsyms] [k] handle_mm_fault
0.78% python3 [kernel.kallsyms] [k] handle_pte_fault
0.78% python3 [kernel.kallsyms] [k] kthread_blkcg
0.78% python3 [kernel.kallsyms] [k] page_counter_try_charge
0.78% python3 [kernel.kallsyms] [k] pmd_val
0.78% python3 [kernel.kallsyms] [k] try_charge_memcg
0.78% python3 [kernel.kallsyms] [k] xas_find
0.78% python3 [kernel.kallsyms] [k] zap_pte_range
0.78% python3 libc.so.6 [.] 0x00000000001a0e5a
0.78% python3 libc.so.6 [.] 0x00000000001a0e76
0.78% python3 libc.so.6 [.] 0x00000000001a0f02
0.78% python3 libc.so.6 [.] 0x00000000001a0f07
0.78% python3 libc.so.6 [.] 0x00000000001a0f27
0.78% python3 libc.so.6 [.] 0x00000000001a0f57
0.78% python3 libc.so.6 [.] 0x00000000001a0f5f
0.78% python3 python3.10 [.] 0x000000000012161a
0.78% python3 python3.10 [.] 0x000000000012d084
I would expect the buff/cache
grows & used
is the same, as the process should reference the data in page cache, any idea on that?我希望buff/cache
增长和used
是相同的,因为进程应该引用页面缓存中的数据,对此有什么想法吗? Any help is appreciated.任何帮助表示赞赏。
no need to copy data from page cache to a process's virtual memory,无需将数据从页面缓存复制到进程的虚拟 memory,
However you explicitly do that here:但是你在这里明确地这样做:
x= mm.read(500000000)
Which uses 500000000 bytes of page cache and requires 500000000 of anonymous memory for bytes
object referred to by the variable x
.它使用 500000000 字节的页面缓存,并且需要 500000000 个匿名 memory 用于变量x
引用的bytes
object。
To avoid copying the file you can use a memoryview
object instead.为避免复制文件,您可以改用内存视图memoryview
。
x = memoryview(mm)[:500000000]
Or alternatively use the mmap
object directly.或者直接使用mmap
object。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.