/dev/shm 写满会触发 Java OOM,因 NIO 的 MappedByteBuffer 依赖 tmpfs 映射,空间耗尽导致 mmap() 失败,抛出 OutOfMemoryError: Map failed;需用 df、ls、dmesg 排查,通过修改 /etc/fstab 永久扩容,并清理残留映射文件。
为什么 /dev/shm 写满会触发 Java OOM?
Java(尤其是 Tomcat)在使用 NIO 时,java.nio.MappedByteBuffer 默认通过 tmpfs 映射文件到内存,底层走的就是 /dev/shm。这个目录本质是内存挂载的 tmpfs 文件系统,大小默认通常只有 64MB(取决于内核版本和发行版)。一旦多个应用或大文件映射反复申请,/dev/shm 耗尽,mmap() 系统调用失败,JVM 就会抛出 OutOfMemoryError: Map failed —— 这不是堆内存不足,而是虚拟内存映射空间被占满。
如何查看当前 /dev/shm 实际大小和使用量?
直接运行命令确认现状,避免盲目调参:
df -h /dev/shm ls -l /dev/shm/ | wc -l # 查看有多少个映射文件(如 tomcat-*.tmp、hsperfdata_*)
常见误判点:看到 df 显示“已用 0”不代表安全——tmpfs 的 inodes 和实际 mmap 区域可能已耗尽,需结合 dmesg | grep -i "shm" 看是否有 Cannot allocate memory 或 Failed to allocate page 日志。
永久调整 /dev/shm 大小的正确方式
不能只改 mount 命令临时生效,Tomcat 启动早于手动 remount,必须确保开机即加载。修改 /etc/fstab 是唯一可靠路径:
立即学习“Java免费学习笔记(深入)”;