私有文件映射,在进程内存种看到的是占用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 。
注意这种方式有两个有用的点:
- 映射的内存是共享的,所以可以多个在多个进程间共享 。
- 对映射的内存写入或修改后,系统会自动同步到对应的文件中,这个很好用 。
- 只要是私有的mmap映射,对于系统看来都是匿名页面 。
- 只要是共享的mmap映射,对系统占用的内存都是MMaped内存 。
#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);}}
注意:- 代码没有调用int shmdt(const void * shmadr); 来清理共享内存和进程的关联;
- 代码也未调用 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 0postgres600566
5.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)
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- linux系统下访问ftp服务器出现中文乱码怎么处理?
- linux系统安装mysql提示初始化失败怎么处理?
- JAVA中计算两个日期时间的差值竟然也有这么多门道
- linux系统下禁止上传目录执行php脚本?
- Linux 压缩命令
- 跳表在Java中的实现
- 生活小窍门美白
- 大学生|丈母娘中意的“女婿职业”排名,榜首意料之中,公务员没进前3
- 中成药|辅警夏季招聘正式开启,面向3类人优先招录,有五险一金!
- 央行|上半年住户存款创近年同期新高 为啥中国人更爱存钱了?专家释疑