linux的内存映射(二)

news2024/11/16 0:30:10

我们先来看幅图:
在这里插入图片描述
Linux内存管理的最底层是buddy内存管理方案,即伙伴算法,管理伙伴算法我们不做详诉,有兴趣的可以自行学习,我们这里只要知道buddy内存池中只能分配2^n个page的内存,比如1,2,4,8……个pages,然而正常使用的时候不会碰巧就需要1,2,4,8……个pages。所以基于buddy内存池,还需要有上一级的内存管理系统,内核里面采用的是slab,slub,slob;而用户空间也有自己的内存管理方案,比如基于glibc的malloc/free内存管理方案。
关于glibc的malloc内存管理方案本文先不做详诉,我们大概了解以下几点,以便对本文的话题有个更加宏观的认识:
如果glibc的内存池中没有内存了,那么malloc就会通过mmap或者brk向buddy申请内存。
free调用不会立即将内存还给buddy,而是会还给glibc的内存池。
如果glibc的内存池中还有足够的内存,那么malloc直接从glibc内存池中分配内存,不会像buddy申请内存。
关于mmap的行为总结下来就是一下几点:

  • mmap的时候只会创建一个vma,此vma也有可能跟之前的vma合并成一个vma,并不会真正的分配物理内存。
  • 当读mmap出来的内存的时候,会发生缺页异常,并将读所涉及到内存都映射到同一个物理页,称为zero page,zero page只有读权限,没有写权限。
  • 当写mmap出来的内存的时候,会在此发生缺页异常,并将所涉及到的内存映射到真实的物理页,并且这些物理页有写权限。
    本文的目的就是从行为以及代码两个方面来印证以上描述。
    mmap代码验证如下:
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>

#define MMAP_SIZE 0x4000
int main(char *argv[], int argc)
{
        int i;
        int tmp;
        void *addr;
        char *p;
        pid_t process_id;
        process_id = getpid();
        printf("pid is %d\n", process_id);
        printf("before mmap\n");
        getchar();
        addr = mmap(NULL, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS,
                  -1, 0);
        printf("after mmap\n");
        getchar();
        p = (char *)addr;
        for(i=0; i< MMAP_SIZE;i++)
                tmp = p[i];

        printf("after read\n");
        getchar();

        for(i=0; i<MMAP_SIZE; i++)
                p[i] = 0x1;

        printf("after write\n");
        getchar();

        return 0;
}

mmap之前的page fault中断以及内存分配情况
执行test程序,打印出before mmap后,通过pidof 找到测试程序的pid为13070,并获取获得如下关键信息:

virtual-machine:~/work$ ps -o maj_flt -o min_flt -p 13070
 MAJFL  MINFL
     0     77
virtual-machine:~/work$ pmap 13070
13070:   ./test
0000000000400000      4K r-x-- test
0000000000600000      4K r---- test
0000000000601000      4K rw--- test
0000000001d10000    132K rw---   [ anon ]
00007f2f56000000   1792K r-x-- libc-2.23.so
00007f2f561c0000   2048K ----- libc-2.23.so
00007f2f563c0000     16K r---- libc-2.23.so
00007f2f563c4000      8K rw--- libc-2.23.so
00007f2f563c6000     16K rw---   [ anon ]
00007f2f563ca000    152K r-x-- ld-2.23.so
00007f2f565d0000     12K rw---   [ anon ]
00007f2f565ef000      4K r---- ld-2.23.so
00007f2f565f0000      4K rw--- ld-2.23.so
00007f2f565f1000      4K rw---   [ anon ]
00007ffc66eab000    132K rw---   [ stack ]
00007ffc66f66000     12K r----   [ anon ]
00007ffc66f69000      8K r-x--   [ anon ]
ffffffffff600000      4K r-x--   [ anon ]
 total             4356K

缺页异常数量是77,所有的vma内存分配如上。前的十六进制数字表示分配该段虚拟内存的起始地址。

after mmap之后搜集信息如下:

virtual-machine:~/work$ ps -o maj_flt -o min_flt -p 13070
 MAJFL  MINFL
     0     77

virtual-machine:~/work$ pmap 13070
13070:   ./test
0000000000400000      4K r-x-- test
0000000000600000      4K r---- test
0000000000601000      4K rw--- test
0000000001d10000    132K rw---   [ anon ]
00007f2f56000000   1792K r-x-- libc-2.23.so
00007f2f561c0000   2048K ----- libc-2.23.so
00007f2f563c0000     16K r---- libc-2.23.so
00007f2f563c4000      8K rw--- libc-2.23.so
00007f2f563c6000     16K rw---   [ anon ]
00007f2f563ca000    152K r-x-- ld-2.23.so
00007f2f565d0000     12K rw---   [ anon ]
00007f2f565eb000     16K rw---   [ anon ]
00007f2f565ef000      4K r---- ld-2.23.so
00007f2f565f0000      4K rw--- ld-2.23.so
00007f2f565f1000      4K rw---   [ anon ]
00007ffc66eab000    132K rw---   [ stack ]
00007ffc66f66000     12K r----   [ anon ]
00007ffc66f69000      8K r-x--   [ anon ]
ffffffffff600000      4K r-x--   [ anon ]
 total             4372K

我们看到page fault没有增加,但是vma增加了一个:

00007f2f565eb000     16K rw---   [ anon ]

那么哪里可以找到实际分配的物理内存的大小呢?可以通过
pmap -x查看,RSS这里是0;方法二,也可以通过可以通过查看/proc/13070/smaps文件来确认

Address           Kbytes     RSS   Dirty Mode  Mapping
...
00007f2f565eb000      16       0       0 rw---   [ anon ]
...
---------------- ------- ------- -------
total kB            4372    1328      80

after read之后信息搜集如下:

virtual-machine:~/work$ ps -o maj_flt -o min_flt -p 13070
 MAJFL  MINFL
     0     81

wqq@wqq-virtual-machine:~/work$ pmap 13070
13070:   ./test
0000000000400000      4K r-x-- test
0000000000600000      4K r---- test
0000000000601000      4K rw--- test
0000000001d10000    132K rw---   [ anon ]
00007f2f56000000   1792K r-x-- libc-2.23.so
00007f2f561c0000   2048K ----- libc-2.23.so
00007f2f563c0000     16K r---- libc-2.23.so
00007f2f563c4000      8K rw--- libc-2.23.so
00007f2f563c6000     16K rw---   [ anon ]
00007f2f563ca000    152K r-x-- ld-2.23.so
00007f2f565d0000     12K rw---   [ anon ]
00007f2f565eb000     16K rw---   [ anon ]
00007f2f565ef000      4K r---- ld-2.23.so
00007f2f565f0000      4K rw--- ld-2.23.so
00007f2f565f1000      4K rw---   [ anon ]
00007ffc66eab000    132K rw---   [ stack ]
00007ffc66f66000     12K r----   [ anon ]
00007ffc66f69000      8K r-x--   [ anon ]
ffffffffff600000      4K r-x--   [ anon ]
 total             4372K

缺页异常增加了四个,因为有4个page被读了嘛!然而Rss没有增加,说明根本没有分配实际的物理内存,完全符合预期。

after write之后信息搜集如下:

virtual-machine:~/work$ ps -o maj_flt -o min_flt -p 13070
 MAJFL  MINFL
     0     85
virtual-machine:~/work$ pmap -x 13070
13070:   ./test
Address           Kbytes     RSS   Dirty Mode  Mapping
...
00007f2f565eb000      16      16      16 rw---   [ anon ]
...
---------------- ------- ------- -------
total kB            4372    1344      96

新增了四个page fault,并且RSS是16K,此时才真正的分配了物理内存。
通过查看/proc/13070/smaps也发现如下:

7f2f565eb000-7f2f565ef000 rw-p 00000000 00:00 0
Size:                 16 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Rss:                  16 kB
Pss:                  16 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:        16 kB
Referenced:           16 kB
Anonymous:            16 kB
LazyFree:              0 kB
AnonHugePages:         0 kB
ShmemPmdMapped:        0 kB
Shared_Hugetlb:        0 kB
Private_Hugetlb:       0 kB
Swap:                  0 kB
SwapPss:               0 kB
Locked:                0 kB
ProtectionKey:         0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/71144.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端面试指南之JS面试题总结

1. JS 有哪些数据类型&#xff1f; 根据 JavaScript 中的变量类型传递方式&#xff0c;分为基本数据类型和引用数据类型两大类七种。 基本数据类型包括Undefined、Null、Boolean、Number、String、Symbol (ES6新增)六种。 引用数据类型只有Object一种&#xff0c;主要包括对象…

pve扩展lvm空间,重做物理卷

pve扩展lvm空间&#xff0c;重做物理卷pve扩展lvm空间&#xff0c;重做物理卷必备知识扩展步骤1.查看当前机器状况2.查看盘符3.确定是否有可分配空间4.确定物理卷分配情况5.&#xff08;可略&#xff09;如果你的空闲的盘已经挂载了请用以下命令卸掉6.创建物理卷7.查看卷状态8.…

day7_redis学习

文章目录Geo查找附近商铺BitMap实现用户签到UV统计Geo查找附近商铺 Geo是GeoLocation的简称&#xff0c;代表地理坐标&#xff0c;在Redis 3.2中加入了对Geo的支持&#xff0c;允许存储地理坐标信息&#xff0c;常见的命令有: ①GEOADD key x y member [x2 y2 member]&#xf…

(一)SpringBoot项目初始化并引入基础文件【木字楠后台管理系统模板】

&#x1f3b6; 文章简介&#xff1a;SpringBoot项目初始化并引入基础文件【木字楠后台管理系统模板】 &#x1f4a1; 创作目的&#xff1a;为了带大家完整的体验木字楠后台管理系统模版的开发流程 ☀️ 今日天气&#xff1a;天气☁️很好。太阳晒在身上暖暖的 &#x1f4dd; 每…

IB数学怎么学,HL是什么难易程度,和SL的内容差的大吗?

做为刚大学毕业的M20 IBer&#xff0c;数学课以往一直没下过90%&#xff0c;全是7分&#xff0c;IA 校园内得分19/20。尽管final被IBO赏了个6&#xff08;大考撤销&#xff0c;ibo蒙蔽估分orz&#xff09;&#xff0c;但我还是汇总了一些自身的数学学习工作经验&#xff0c;期待…

一个变量命名神器:支持中文转变量名

变量命名的规范&#xff0c;对于我们编程&#xff0c;大家都知道是非常重要的&#xff0c;上次给大家推荐过一个命名辅助工具《程序员还在为变量取名苦恼&#xff0c;那是因为你不知道&#xff0c;这个变量命名神器》&#xff0c;但大家一致反馈存在2个问题&#xff1a; 1、网…

项目管理(如何进行项目采购管理)

项目采购管理包括从项目团队外部采购或获取所需产品、服务或成果的各个过程。项目采购管 理包括编制和管理协议所需的管理和控制过程,例如,合同、订购单、协议备忘录 (MOA),或服务 水平协议 (SLA)。被授权采购项目所需货物和(或)服务的人员可以是项目团队、管理层或组织采…

使用winhex对fat16文件系统分析

“FAT16”是“File Allocation Table,16-bit”的英文缩写,意思是“文件分配表,16位” 。FAT16文件系统是从微软的DOS 3.0系统开始使用的&#xff0c;它能够支持大于16MB小于2GB的分区&#xff0c;Windows 2000以上操作系统可以创建4GB的FAT16分区&#xff0c;但与传统的FAT16不…

【观察】深度剖析,为什么说帆软的文化决定了FineBI6.0的易用和好用

毫无疑问&#xff0c;今天国家对数字经济给予了前所未有的高度重视&#xff0c;《“十四五”数字经济发展规划》中&#xff0c;就明确将继续坚持推进数字产业化和产业数字化&#xff0c;赋能传统产业转型升级&#xff0c;为构建数字中国提供有力支撑&#xff0c;并提出到2025年…

FFmpeg之硬解码

导读 众所周知&#xff0c;软解码虽然兼容性一流&#xff0c;但是却非常依赖CPU&#xff0c;所以性能消耗笔记大&#xff1b;硬解码使用内置的DSP芯片进行解码&#xff0c;性能高&#xff0c;但是兼容性一般。 虽说硬解码兼容性不太好&#xff0c;但是在实际开发中出于对性能的…

智能化煤矿-设备管理系统、故障诊断、全生命周期管理

随着智能化煤矿的建设&#xff0c;煤矿设备、传感器数量在增加、煤矿设备的自动化、智能化程度也相对提高。保证设备稳定运行&#xff0c;减少故障时间是提高煤矿安全生产的一种重要途径。另外随着信息技术的发展&#xff0c;像云计算、物联网、大数据等相关技术的运用&#xf…

vue2的 webpack-bundle-analyzer 打包体积 看优化包

1、 先安装 npm i webpack-bundle-analyzer -D 2、 vue.config 文件中 配置 /* webpack相关配置 *该对象将会被 webpack-merge 合并入最终的 webpack 配置 */ if (process.env.use_analyzer) { // 分析 config .plugin(webpack-bundle-analyzer) .use(require(webpa…

XuperSocial首个明星DApp上线,探索区块链分布式通信基础设施

12月7日&#xff0c;星际口袋上线星际社区&#xff0c;为广大藏友提供稳定、可信的交流场所。星际社区基于百度超级链团队重磅发布的去平台化社交解决方案XuperSocial搭建&#xff0c;XuperSocial是架设在百度超级链开放网络&#xff08;XuperOS&#xff09;上的DApp&#xff0…

Oracle PrimaveraUnifier 之数据要素(Data Element)

目录 一&#xff1a;什么是数据要素 二&#xff1a;常用的数据要素 一&#xff1a;什么是数据要素 数据要素是Oracle Primavera Unifier维护业务单据/表达的最小单元&#xff0c;也就是我们常说的字段&#xff0c;它将数据定义与字段标签相结合&#xff0c;成为我们用户在 P…

Runtime源码解析-类中bits

Runtime源码解析-类中bits class_rw_t ro_or_rw_ext_t 成员变量方法 初始化方法存取方法类型判断 公有方法 获取class_rw_ext_t获取/设置class_ro_t方法、属性、协议列表 class_rw_ext_tclass_ro_t总结 1. 为什么ro_or_rw_ext 会有两种类型&#xff0c;class_rw_ext_t或者cla…

Sping Boot 如何实现自动配置

Sping Boot 如何实现自动配置 Spring Boot都需要创建一个mian启动类&#xff0c;而启动类都含有SpringBootApplication注解&#xff0c;从启动类&#xff0c;一步步探索源码。 SpringBootApplication注解 Spring Boot 启动类上都有一个 SpringBootApplication注解&#xff1…

想知道CAD怎么转换为PDF吗?快来收藏这些实用的转换技巧

有一些读建筑类或者电子信息类专业的小伙伴&#xff0c;经常需要使用到CAD软件来设计和修改图纸&#xff0c;并且保存下来的文件一般默认是CAD文件格式。但有的时候&#xff0c;我们将图纸发送给其他人&#xff0c;对方的设备中没有相应的软件&#xff0c;导致无法查看&#xf…

Linux 进程间通信:匿名管道 命名管道 共享内存

进程间通信的必要性 进程间通信&#xff0c;是建立在多进程之上的。如果是单进程&#xff0c;则无法使用并发能力&#xff0c;更加无法进行多进程协同。多进程要想实现多进程协同&#xff08;目的&#xff09;&#xff0c;就必须进行进程间通信&#xff08;手段&#xff09;。…

知识图谱-KGE-语义匹配-双线性模型-2018:SimplE

【paper】 SimplE Embedding for Link Prediction in Knowledge Graphs【简介】 本文是加拿大英属哥伦比亚大学的两位学者发表在 NIPS 2018 上的工作&#xff0c;文章提出了 SimplE&#xff08;Simple Embedding&#xff09;。这篇和前面一篇差不多&#xff0c;也是对 1927 年的…

深度学习 +SLAM:SuperGlue

简介 传统SLAM的流程通常包括如下内容&#xff0c; 特征点提取描述&#xff0c;特征点匹配 异常点去除&#xff0c; 位姿估计。 在以往前人的工作中&#xff0c;SuperPoint和 D2-Net试图解决特征点检测和描述的问题。而检测之后的匹配通常通过最近邻匹配和异常点剔除的方式完…