linux中申请内存的情况分析( 四 )

私有文件映射,在进程内存种看到的是占用Inactive(file)内存,只所以也会占用Inactive(anon),是在于私有文件映射很特殊,它在写的时候,不会同步到后台的文件上去,采用写时复制,写时候会拷贝一份到物理内存中(匿名内存) 。
5.5 mmap申请共享文件映射代码和上面类似不同点:
ptr = mmap(NULL, MEMSIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);结果如下:
1. MemFree 少1GB 。2. Cached 增加了1GB 。3. Inactive 增加了1GB 。4. Inactive(file) 增加了1GB 。5. Mapped 增加了1GB 。注意只有共享内存的mmap才会在Mapped内存,共享内存映射算Cache所以这里面增加了,因为第一次读文件,所以是Inactive(file),所以增加了1GB 。
注意这种方式有两个有用的点:

  1. 映射的内存是共享的,所以可以多个在多个进程间共享 。
  2. 对映射的内存写入或修改后,系统会自动同步到对应的文件中,这个很好用 。
总结
  1. 只要是私有的mmap映射,对于系统看来都是匿名页面 。
  2. 只要是共享的mmap映射,对系统占用的内存都是MMaped内存 。
5.6 shm共享内存代码如下:
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/ipc.h>#include <sys/shm.h>#include <string.h>#define MEMSIZE 1024*1024*1024intmain(){int shmid;char *ptr;pid_t pid;struct shmid_ds buf;int ret;// 创建1GB大小权限为0600的共享内存shmid = shmget(IPC_PRIVATE, MEMSIZE, 0600);if (shmid<0) {perror("shmget()");exit(1);}// 获取共享内存信息复制到buf中,包括权限大小等ret = shmctl(shmid, IPC_STAT, &buf);if (ret < 0) {perror("shmctl()");exit(1);}printf("shmid: %dn", shmid);printf("shmsize: %dn", buf.shm_segsz);pid = fork();if (pid<0) {perror("fork()");exit(1);}// 子进程if (pid==0) {// 将共享内存映射到本进程的内存空间ptr = shmat(shmid, NULL, 0);if (ptr==(void*)-1) {perror("shmat()");exit(1);}bzero(ptr, MEMSIZE);// 拷贝hello到里面去strcpy(ptr, "Hello!");exit(0);} else {// 等子进程写入结束wait(NULL);// 将共享内存映射到本进程的内存空间ptr = shmat(shmid, NULL, 0);if (ptr==(void*)-1) {perror("shmat()");exit(1);}// 输出退出puts(ptr);exit(0);}}注意:
  1. 代码没有调用int shmdt(const void * shmadr); 来清理共享内存和进程的关联;
  2. 代码也未调用 shmctl的IPC_RMID删除共享内存 来删除内存,所以程序运行结束,还是会占用共享内存的,如下查看:
root@ubuntu-lab:/home/miao/c-test/mm-test# ipcs -m------ Shared Memory Segments --------keyshmidownerpermsbytesnattchstatus0x000631ba 0postgres6005660x00000000 3root6001073741824 0继续看下内存的变化:
1. MemFree 和MemAvailable 减少了1GB 。2. Cached 占用增加了1GB,可见shm是属于cache的 。3. Inactive 增加了1GB 。4. Inactive(anon) 增加了1GB 。5. Shmem 增加了1GB 。6. Committed_AS增加了1GB 。shm被视为基于tmpfs文件系统的内存页,既然基于文件系统,就不算匿名页,所以不被计入/proc/meminfo中的AnonPages 。
清理共享内存:
root@ubuntu-lab:/home/miao/c-test/mm-test# ipcrm -m 3root@ubuntu-lab:/home/miao/c-test/mm-test# ipcs -m------ Shared Memory Segments --------keyshmidownerpermsbytesnattchstatus0x000631ba 0postgres6005665.7 tmpfs测试:
mkdir /tmp/tmpfsmount -t tmpfs -o size=2G none /tmp/tmpfs/#占用空间root@ubuntu-lab:/home/miao/c-test/mm-test# dd if=/dev/zero of=/tmp/tmpfs/testfile bs=1G count=11+0 records in1+0 records out1073741824 bytes (1.1 GB, 1.0 GiB) copied, 3.15495 s, 340 MB/sroot@ubuntu-lab:/home/miao/c-test/mm-test# root@ubuntu-lab:/home/miao/c-test/mm-test# df -hnone2.0G1.0G1.0G50% /tmp/tmpfs内存变化:
1. MemFree 和MemAvailable 减少了1GB 。2. Cached 占用增加了1GB,可见shm是属于cache的 。3. Inactive 增加了1GB 。4. Inactive(anon) 增加了1GB 。5. Shmem 增加了1GB 。6. Committed_AS增加了1GB 。和shm一样的内存变化,注意用:echo 3 > /proc/sys/vm/drop_caches 并不会释放内存,而且通过free -h 可以看到有1GB的空间 。
root@ubuntu-lab:/home/miao/c-test/mm-test# free -htotalusedfreesharedbuff/cacheavailableMem:4.7Gi474Mi3.0Gi1.0Gi1.2Gi3.0Gi清理:
rm /tmp/tmpfs/testfile umount/tmp/tmpfs/参考:[linux内存占用分析之meminfo - SegmentFault 思否](https://segmentfault.com/a/1190000022518282)[/proc/meminfo之谜 | Linux Performance](http://linuxperf.com/?p=142)代码来自:深入浅出Linux 内核管理和调试[https://www.jianshu.com/p/eece39beee20](https://www.jianshu.com/p/eece39beee20)


推荐阅读