/proc/$pid/maps中"deleted"字段含义解析(libhugetlbfs场景)
先给你梳理下核心逻辑:(deleted)这个标记的意思是,进程当前映射的文件已经被从文件系统中删除了,但因为进程还握着这个文件的引用(要么是打开的文件描述符,要么是内存映射),内核不会立刻清理对应的inode,所以这个映射依然能正常工作,完全不影响程序运行。
接下来针对你看到的两个条目逐一拆解:
1. /mnt/SharedMem_2M/libhugetlbfs.tmp.85Y41e (deleted)
这个是libhugetlbfs启动时自动创建的临时文件,作用是把程序的部分内存段(比如一些全局符号、程序段)映射到大页上——从你的调试日志里能看到这句:Mapped hugeseg at 0x2aaaaac00000. Copying 0x274 bytes and 0x14 extra bytes from 0x600de0...done,就是在把程序的部分内容复制到这个大页映射里。
libhugetlbfs的套路是:创建这个临时文件后马上删掉它,这样既不会在你的hugetlbfs挂载点(/mnt/SharedMem_2M)留下垃圾文件,又能通过已打开的文件描述符继续使用这个大页映射。所以在/proc/maps里就会显示(deleted),毕竟文件在磁盘上已经不存在了,但进程还在用到它的内存。
2. /anon_hugepage (deleted)
这个条目对应你代码里的malloc分配的堆内存,还有全局数组glbarr的内存——因为你设置了HUGETLB_MORECORE=yes,libhugetlbfs直接接管了C标准库的内存分配逻辑,把堆和全局数据都放到了大页上。
这里的/anon_hugepage其实是内核用来管理匿名大页的虚拟"文件"(内核内部用anon_inode机制实现),(deleted)标记说明这个虚拟文件没有对应的磁盘路径——说白了就是这是纯内存里的大页,没有实际的磁盘文件关联,进程用完之后,只要一退出,内核就会自动回收这部分大页内存。
再结合你的数据验证下:你看到numastat显示用了8M大页,是因为大页是按2MB粒度分配的——你的glbarr是int[1024*1024],每个int占4字节,算下来是4MB;malloc(1MB)会被向上对齐到2MB;再加上libhugetlbfs自身的临时段映射(2MB),加起来刚好8MB,完全对得上。
总的来说,这两个(deleted)标记都是libhugetlbfs正常工作的表现,不用慌,进程退出后这些大页都会被内核正确回收。
内容的提问来源于stack exchange,提问作者barfatchen

