DAY13-Linux内核内存布局

【搜索微信公众号】百万年薪运维工程师手札

让我们一同为了理想前进

Linux内核内存布局

64位Linux一般使用48位来标识虚拟地址空间,45位标识物理地址。通过命令cat /proc/cpuinfo可以查看地址大小。其实也可以用lscpu查看,两者查看的内容来源是一致的。

CPUINFO信息

processor : 0

vendor_id : GenuineIntel //CPU制造商

cpu family : 6 //CPU产品代号

model : 154 //CPU属于其系列中的哪个代号

model name : 12th Gen Intel(R) Core(TM) i7-1280P //CPU的名称,编号,主频

stepping : 3 //CPU属于制作更新版本

microcode : 0x421

cpu MHz : 1996.800 //CPU实际使用的主频

cache size : 24576 KB //CPU二级缓存

physical id : 0 //单个CPU的标号

siblings : 4 //单个CPU逻辑物理合数

core id : 0 //当前物理核在其所处的CPU中编号

cpu cores : 4 //逻辑核所在CPU的物理核数

apicid : 0 //用来区分不同逻辑核的编号

bogomips : 3993.60 //系统内核启动时测算的CPU速度

clflush size : 64 //每次刷新缓存的大小单位

cache_alignment : 64 //缓存地址空间对齐单位

address sizes : 45 bits physical, 48 bits virtual //可以访问的地址空间的位数

MEMINFO信息

[root@TEST ~]# cat /proc/meminfo

MemTotal: 3488048 kB //所有可用内存空间大小

MemFree: 3012560 kB //系统还没有使用内存

MemAvailable: 2948008 kB //系统真正可用内存

Buffers: 20424 kB //专用用来给块设备做缓存的内存

Cached: 203764 kB //分配给文件缓冲区的内存

SwapCached: 0 kB

Active: 167832 kB // 使用高速缓存存储器页面文件大小

Inactive: 122852 kB //没有经常使用的高速缓存存储器大小

Active(anon): 77860 kB //活跃的匿名内存

Inactive(anon): 7324 kB //不活跃的匿名内存

Active(file): 89972 kB //活跃的文件使用内存

Inactive(file): 115528 kB //不活跃的文件使用内存

Unevictable: 11044 kB //不能被释放的内存页

Mlocked: 11044 kB //系统调用mlock允许程序在物理内存上锁住部分地址空间

SwapTotal: 3145724 kB

SwapFree: 3145724 kB

Dirty: 0 kB //等待被刷入磁盘的数据(脏页)

Writeback: 0 kB //正在被写入的数据

AnonPages: 75508 kB //未映射页的内存/映射到用户空间的非文件页表大小

Mapped: 58840 kB //映射文件内存

Shmem: 9352 kB //已经被分配的共享内存

Slab: 78704 kB //内存数据结构缓存大小

SReclaimable: 37528 kB //可回收slab大小

CommitLimit: 4889748 kB //系统实际可以分配内存

Committed_AS: 362004 kB //系统当前已经分配的内存

VmallocTotal: 34359738367 kB //预留虚拟内存的总量

VmallocUsed: 0 kB //已经被使用的虚拟内存

VmallocChunk: 0 kB //可分配的最大逻辑地址连续的虚拟内存

Linux动态内存分配接口

Linux内核动态内存分配通过系统接口实现

alloc_pages/__get_free_page: 以页为单位分配

vmalloc: 以字节为单位分配虚拟地址连续的内存块

kmalloc:以字节为单位分配物理地址连续的内存块,以slab为中心,

同样也可以通过vmalloc分配的内存进行统计输出

ARM64架构采用48为物理寻址方式,最大可寻找256TB的物理地址空间,虚拟地址同样也支持48位寻址。

Linux内核将上述地址分为:用户空间和内核空间

用户空间地址为0x0000 0000 0000 0000 到0x0000 FFFF FFFF FFFF

内核空间地址为0xFFFF 0000 0000 0000 到0xFFFF FFFF FFFF FFFF

Linux内核内存布局

Linux内核内存布局(ARM64架构处理器内存分布)

KASAN(影子区): 它是一个动态检测内存错误的工具,原理利用额外的内存标记可用内存状态,将1/8区域用作影子区

modules: 内核模块使用的虚拟地址空间

vmalloc: vmalloc函数使用的虚拟地址空间

.text: 代码段

.init: 模块初始化数据

.data: 代表数据段

.bss: 静态内存分配段

fixed: 固定映射区域

PCI I/O:针对PCI设备的I/O地址空间

vmemmap: 内存的物理地址,如果不连续的话,就会存在内存空洞(稀疏内存), vmmemmap就是用来存放稀疏内存的page结构体的数据的虚拟地址空间

memory: 线性映射区域

我们可以通过内存布局打印输出(Linux内核初始化完成后,整体布局稳定,通过Vexpress平台输出即可):

通过start_kernel函数->mm_init->mem_init->分配内存初始化

堆管理

堆是进程中主要用于动态分配变量和数据的内存区域,堆的管理对应程序员不是直接可见的。malloc和内核之间的经典接口是brk系统调用,负责扩展/收缩堆。

堆是一个连续的内存区域,在扩展时自下至上增长。其中mm_struct结构,包含堆在虚拟地址空间中的起始和当前结束地址(start_brk和brk)

内存描述mm_struct结构体当中,有堆起始地址和结束地址的成员

brk系统调用内核源码

Linux系统有两个方法可以调用创建堆(heap)

brk()是系统调用,实际是设置进程数段的结束地址,将数据段的结束地址向高地址移动

mmap()向操作系统申请一段虚拟地址空间(使用映射到某个文件),当不用此空间来映射到某个文件时,这块空间称为匿名空间,可以用来作为堆空间

per-CPU计数器

引入用来加速SMP系统上计数器操作,内核代码如下:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值