MappedByteBuffer映射大文件时物理内存不立即增长,仅按需分页加载;初始RSS可能仅几MB,实际占用取决于访问模式,未访问区域只占虚拟地址空间,不消耗RAM。

MappedByteBuffer 映射大文件时,**物理内存(RAM)不会立即增长,也不等于文件大小**。它只在真正访问数据时,由操作系统按页(通常 4KB)加载进物理内存——这是核心事实。
物理内存实际占用取决于访问模式,不是映射动作本身
映射一个 50GB 文件,初始 RSS(常驻内存)可能仅几 MB。只有当你调用 get()、put() 或 load() 访问某段偏移时,才触发缺页中断,内核把对应磁盘页载入物理内存。未触达的区域始终只占虚拟地址空间,不消耗 RAM。
- 顺序读取局部区域(如扫描前 100MB):物理内存峰值 ≈ 实际读取量 + OS 页面缓存冗余
- 随机跳转访问分散位置(如每 1GB 取 1KB):频繁缺页 → 内存碎片化 + 缓存抖动 → RSS 持续攀升,甚至触发 OOM Killer
- 仅映射但完全不访问:RSS 几乎无增长,但会占用进程虚拟地址空间和内核 VMA 条目
物理内存压力来自三类隐性开销
即使你“只读”,OS 仍可能为 mmap 分配额外物理资源:
- 页面缓存复用冲突:mmap 与普通 read() 共享同一套 page cache。若同时有大量传统 I/O,mmap 热页可能被踢出,反复换入换出
- 写时复制(COW)开销(PRIVATE 模式):每次修改都会复制整页(4KB),哪怕只改 1 字节,导致物理内存翻倍增长
- 脏页回写延迟:READ_WRITE 模式下,修改后 OS 异步刷盘。若写入速率 > 刷盘能力,脏页堆积 → 占用更多 RAM,且可能阻塞后续写操作
不能只看 top 的 RES,要查 /proc/pid/smaps 才知真相
Linux 中,top 的 RES 值包含共享内存、匿名映射、页面缓存等混合项,严重高估 mmap 真实独占内存。应关注:
立即学习“Java免费学习笔记(深入)”;
- MMAP 区域的 Pss(Proportional Set Size):反映该进程对共享页的实际“分摊”内存占用
- Rss 中属于 anon-rss 的部分:真正私有的物理页(如 COW 复制页)
- Dirty 和 Writeback 字段:判断脏页积压程度


















