linux mmap申请内存后,munmap释放报错12(ENOMEM)

jianpanlanyue 2018-12-27 04:26:03
环境:64位的centos7.2(3.10.0-327)或centos7.4(3.10.0-693),系统刚重启过,无业务压力,物理内存也足够,还剩十几G。

现象:
mmap每次申请4k内存页,连续申请1024*1024次(共4G),成功,top 和 /proc/smaps 中可以看到占用4G左右物理内存。
然后,针对每个内存页,调用munmap。 但是部分munmap失败,error是12(ENOMEM)。 top 和 /proc/smaps中显示,还占用1.6G物理内存。

疑问:
申请的时候是按页的粒度成功分配的,释放的时候也是按页的粒度做的释放,为什么munmap会报12(内存不足)?
另外,如果去掉(i%11==0 || i%197==0 || i%393==0)这个条件,则munmap不报错。 但是,我并没有跨页释放。

代码如下:
#include <iostream>
#include <memory.h>
#include <sys/mman.h>
#include <errno.h>
#include <assert.h>

#define PAGE_SIZE 4096
#define PAGE_COUNT 1024*1024

int main()
{
std::string str;
void** table = new void*[PAGE_COUNT];

std::cout << "begin mmap..." << std::endl;
for (int i=0; i<PAGE_COUNT; i++) {
table[i] = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1 ,0);
assert(table[i] != MAP_FAILED);
memset(table[i], 1, PAGE_SIZE);
}

std::cout << "mmap finish. input any str and enter to begin munmap..." << std::endl;
std::cin >> str;
for(int i=0; i<PAGE_COUNT; i++) {
if (i%11==0 || i%197==0 || i%393==0)
continue;
if (munmap(table[i], PAGE_SIZE) != 0)
std::cout << errno << std::endl;
}

delete[] table;
std::cin >> str;
return 0;
}
...全文
657 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
fly 100% 2018-12-30
  • 打赏
  • 举报
回复
你这个table 的结构体好像有点问题,打印出来看看吧

23,125

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧