从man页,
MAP_ANONYMOUS The mapping is not backed by any file; its contents are initialized to zero. The fd and offset arguments are ignored; however,some implementations require fd to be -1 if MAP_ANONYMOUS (or MAP_ANON) is specified,and portable applications should ensure this. The use of MAP_ANONYMOUS in conjunction with MAP_SHARED is only supported on Linux since kernel 2.4.
使用MAP_ANONYMOUS的目的是MAP_ANONYMOUS ? 任何例子都不错。 也从内存的映射?
它写在man页上, The use of MAP_ANONYMOUS in conjunction with MAP_SHARED is only supported on Linux since kernel 2.4. 我怎样才能与其他进程共享与MAP_ANONYMOUS映射的内存?
memset可以在4核上并行化吗?
Linux c应用程序内存使用情况
Linux上的Java内存使用情况
为什么node.js进程占用的内存比分配的多
LeakDiag为64位Windows?
我怎样才能得到我的程序的内存消耗高峰?
如何随着时间的推移监视一个进程的内存使用情况 – Ubuntu的
内存泄漏使用malloc失败
如何在基于Linux的embedded式设备上导致内存碎片?
匿名映射可以被描绘成一个零化的虚拟文件。 匿名映射只是大量的,填满零的内存块准备使用。 这些映射驻留在堆外部,因此不会导致数据段碎片。
MAP_ANONYMOUS + MAP_PRIVATE:
每个电话都会创建一个独特的映射
孩子继承父母的映射
儿童对继承的映射的写作是以写时复制的方式进行的
使用这种映射的主要目的是分配一个新的归零内存
malloc使用匿名私有映射为大于MMAP_THRESHOLD字节的内存分配请求提供服务。
通常,MMAP_THRESHOLD是128kB。
MAP_ANONYMOUS + MAP_SHARED:
孩子继承父母的映射
当共享映射的其他人写入共享映射时没有写入时复制
共享匿名映射允许IPC以类似于系统V内存段的方式,但仅在相关的进程之间
在Linux上,有两种方法来创建匿名映射:
指定MAP_ANONYMOUS标志并为fd传递-1
addr = mmap(NULL,length,PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS,-1,0); if (addr == MAP_Failed) exit(EXIT_FAILURE);
打开/ dev / zero并传递这个打开的fd
fd = open("/dev/zero",O_RDWR); addr = mmap(NULL,MAP_PRIVATE,fd,0);
(这种方法通常用于像BSD这样的没有MAP_ANONYMOUS标志的系统)
匿名映射的优点:
– 没有虚拟地址空间碎片; 取消映射后,内存立即返回到系统
– 它们可以根据分配大小,权限进行修改,而且它们也可以像正常映射一样接收建议
– 每个分配都是独立的映射,与全局堆分开
匿名映射的缺点:
– 每个映射的大小是系统页面大小的整数倍,因此会导致地址空间的浪费
– 创建和返回映射会比预先分配的堆产生更多的开销
如果一个包含这样的映射的程序分叉了一个进程,那么这个孩子将继承这个映射。 下面的程序演示了这种继承:
#ifdef USE_MAP_ANON #define _BSD_SOURCE #endif #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <sys/wait.h> #include <sys/mman.h> #include <fcntl.h> #include <unistd.h> int main(int argc,char *argv[]) { /*Pointer to shared memory region*/ int *addr; #ifdef USE_MAP_ANON /*Use MAP_ANONYMOUS*/ addr = mmap(NULL,sizeof(int),0); if (addr == MAP_Failed) { fprintf(stderr,"mmap() Failedn"); exit(EXIT_FAILURE); } #else /*Map /dev/zero*/ int fd; fd = open("/dev/zero",O_RDWR); if (fd == -1) { fprintf(stderr,"open() Failedn"); exit(EXIT_FAILURE); } addr = mmap(NULL,MAP_SHARED,"mmap() Failedn"); exit(EXIT_FAILURE); } if (close(fd) == -1) { /*No longer needed*/ fprintf(stderr,"close() Failedn"); exit(EXIT_FAILURE); } #endif *addr = 1; /*Initialize integer in mapped region*/ switch(fork()) { /*Parent and child share mapping*/ case -1: fprintf(stderr,"fork() Failedn"); exit(EXIT_FAILURE); case 0: /*Child: increment shared integer and exit*/ printf("Child started,value = %dn",*addr); (*addr)++; if (munmap(addr,sizeof(int)) == -1) { fprintf(stderr,"munmap()() Failedn"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); default: /*Parent: wait for child to terminate*/ if (wait(NULL) == -1) { fprintf(stderr,"wait() Failedn"); exit(EXIT_FAILURE); } printf("In parent,*addr); if (munmap(addr,"munmap()() Failedn"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }
资料来源:
Linux编程接口
第49章:内存映射
作者:Michael Kerrisk
Linux系统编程(第三版)
第8章:内存管理,
作者:罗伯特·爱
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。