物理内存的组织方式

  • 物理内存是由连续的一页一页的块组成,每个物理页都有页号
  • 每个页由struct page表示,放进数组里——平坦内存模型

SMP和NUMA

  • SMP中,总线会称为瓶颈,因为数据都要经过它
  • NUMA中
    • 每个CPU都有本地内存,CPU访存不用过总线
    • 但本地内存不足时,每个CPU可以去另外的NUMA节点申请内存,延时较长
    • NUMA基本是非连续内存模型,非连续内存模型不一定就是NUMA
typedef struct pglist_data
{
struct zone node_zones[MAX_NR_ZONES]; // 每个节点还会分成一个个区域zone
struct zonelist node_zonelists[MAX_ZONELISTS]; // 备用节点
int nr_zones;
struct page *node_mem_map; // 此节点的struct page数组
unsigned long node_start_pfn; // 起始页号
unsigned long node_present_pages; /* total number of physical pages */
unsigned long node_spanned_pages; /* total size of physical page range, including holes */
int node_id; // 自己的id
......
} pg_data_t;

举个例子:

64M 物理内存隔着一个 4M 的空洞,然后是另外的 64M 物理内存。 换算成页面数目就是,16K 个页面隔着 1K 个页面,然后是另外 16K 个页面。这种情况下,node_spanned_pages 就是 33K 个页面,node_present_pages 就是 32K 个页面。

ZONE_DMA

ZONE_DMA可用于做直接内存存取的内存。

DMA机制:

要把外设的数据读入内存或把内存的数据传送到外设,原来都要通过 CPU 控制完成,但是这会占用 CPU,影响 CPU 处理其他事情,所以有了 DMA 模式。CPU 只需向 DMA 控制器下达指令,让 DMA 控制器来处理数据的传送,数据传送完毕再把信息反馈给 CPU,这样就可以解放 CPU。

64位系统有两个DMA系统,除了ZONE_DMA还有ZONE_DMA32

区域

上面把内存分成了节点,把节点分成了区域。区域zone的定义:

struct zone {
......
struct pglist_data *zone_pgdat;
struct per_cpu_pageset __percpu *pageset; // 用于区分冷热页 unsigned long zone_start_pfn; // 表示属于这个zone的第一页 /*
* spanned_pages is the total pages spanned by the zone, including
* holes, which is calculated as:
* spanned_pages = zone_end_pfn - zone_start_pfn;
*
* present_pages is physical pages existing within the zone, which
* is calculated as:
* present_pages = spanned_pages - absent_pages(pages in holes);
*
* managed_pages is present pages managed by the buddy system, which
* is calculated as (reserved_pages includes pages allocated by the
* bootmem allocator):
* managed_pages = present_pages - reserved_pages;
*
*/
unsigned long managed_pages; // 此zone被伙伴系统管理的所有page数目
unsigned long spanned_pages; // 包括中间的物理内存空洞
unsigned long present_pages; // 物理内存中真实存在的page数 const char *name;
......
/* free areas of different sizes */
struct free_area free_area[MAX_ORDER]; /* zone flags, see below */
unsigned long flags; /* Primarily protects free_area */
spinlock_t lock;
......
} ____cacheline_internodealigned_in_

什么是冷热页?

x86 体系结构中,为了让 CPU 快速访问段描述符,在 CPU 里面有段描述符缓存。CPU 访问这个缓存的速度比内存快得多。同样对于来讲,也是这样的。如果一个页被加载到 CPU 高速缓存里面,这就是一个热页(Hot Page),CPU 读起来速度会快很多,如果没有就是冷页(Cold Page)。由于每个 CPU 都有自己的高速缓存,因而 per_cpu_pageset 也是每个 CPU 一个。

页(Page)

一个物理页面可以使用多种模式:

  • 要用就用一整页

    • 匿名页:一整页的内存,或者直接和虚拟地址空间建立映射关系
    • 内存映射文件:或者用于关联一个文件,然后再和虚拟地址空间建立映射关系
    • 每个进程都有自己的页表
  • 仅需分配小块内存
    • Linux采用了slab allocator 的技术,用于分配称为slab的小块内存
    • 基本原理:
      • 从内存管理模块申请一整块页
      • 划分成多个小块的存储池,用复杂的队列维护小块的状态
      • 状态包括:被分配了/被放回池子/应该被回收

Linux中把所有空闲页分为了11个页块链表,每个块链表分别包含很多个大小的页块,有1、2、4、8、16、32、64、128、512和1024个连续的页块。

请求分配页块时,依次按照更大的页块链表去找。分配的页块有多余的页时,伙伴系统会根据多余的页块大小,插入到对应的空闲页块链表中。

举个栗子:

要请求一个 128 个页的页块时,先检查 128 个页的页块链表是否有空闲块。如果没有,则查 256 个页的页块链表;如果有空闲块的话,则将 256 个页的页块分成两份,一份使用,一份插入 128 个页的页块链表中。如果还是没有,就查 512 个页的页块链表;如果有的话,就分裂为 128、128、256 三个页块,一个 128 的使用,剩余两个插入对应页块链表。

小结

  • 如果有多个 CPU,那就有多个节点。每个节点用 struct pglist_data 表示,放在一个数组里面。
  • 每个节点分为多个区域,每个区域用 struct zone 表示,也放在一个数组里面。
  • 每个区域分为多个页。为了方便分配,空闲页放在 struct free_area 里面,使用伙伴系统进行管理和分配,每一页用 struct page 表示。

Linux — 物理内存管理的更多相关文章

  1. 一步一图带你深入理解 Linux 物理内存管理

    1. 前文回顾 在上篇文章 <深入理解 Linux 虚拟内存管理> 中,笔者分别从进程用户态和内核态的角度详细深入地为大家介绍了 Linux 内核如何对进程虚拟内存空间进行布局以及管理的相 ...

  2. linux物理内存管理

    1.为什么需要连续的物理内存: Linux内核管理物理内存是通过分页机制实现的,它将整个内存划分成无数个4k(在i386体系结构中)大小的页,从而分配和回收内存的基本单位便是内存页了.利用分页管理有助 ...

  3. 深入理解 Linux 物理内存分配全链路实现

    前文回顾 在上篇文章 <深入理解 Linux 物理内存管理>中,笔者详细的为大家介绍了 Linux 内核如何对物理内存进行管理以及相关的一些内核数据结构. 在介绍物理内存管理之前,笔者先从 ...

  4. Linux内存管理 (1)物理内存初始化

    专题:Linux内存管理专题 关键词:用户内核空间划分.Node/Zone/Page.memblock.PGD/PUD/PMD/PTE.lowmem/highmem.ZONE_DMA/ZONE_NOR ...

  5. LInux中的物理内存管理

    2017-02-23 一.伙伴系统 LInux下用伙伴系统管理物理内存页,伙伴系统得益于其良好的算法,一定程度上可以避免外部碎片为何这么说?先回顾下Linux下虚拟地址空间的分布. 在X86架构下,系 ...

  6. Linux内存:物理内存管理概述

    内存中的物理内存管理 概述 一般来说,linux内核一般将处理器的虚拟地址空间划分为2部分.底部比较大的部分用于用户进程,顶部则专用于内核. 在IA-32系统上,地址空间在用户进程和内核之间划分的典型 ...

  7. 浅谈Linux内存管理机制

    经常遇到一些刚接触Linux的新手会问内存占用怎么那么多?在Linux中经常发现空闲内存很少,似乎所有的内存都被系统占用了,表面感觉是内存不够用了,其实不然.这是Linux内存管理的一个优秀特性,在这 ...

  8. linux内存管理

    一.Linux 进程在内存中的数据结构 一个可执行程序在存储(没有调入内存)时分为代码段,数据段,未初始化数据段三部分:    1) 代码段:存放CPU执行的机器指令.通常代码区是共享的,即其它执行程 ...

  9. Linux内存管理原理

    本文以32位机器为准,串讲一些内存管理的知识点. 1. 虚拟地址.物理地址.逻辑地址.线性地址 虚拟地址又叫线性地址.linux没有采用分段机制,所以逻辑地址和虚拟地址(线性地址)(在用户态,内核态逻 ...

  10. 了解linux内存管理机制(转)

    今天了解了下linux内存管理机制,在这里记录下,原文在这里http://ixdba.blog.51cto.com/2895551/541355 根据自己的理解画了张图: 下面是转载的内容: 一 物理 ...

随机推荐

  1. KingbaseES V8R3 表加密

    前言 透明加密是指将数据库page加密后写入磁盘,当需要读取对应page时进行加密读取.此过程对于用户是透明, 用户无需干预. 该文档进行数据库V8R3版本测试透明加密功能,需要说明,该版本发布时间早 ...

  2. 谈谈 OI 中的查重

    鉴于最近洛谷的公开赛出现的重题引起的纠纷,我打算整理一下此类问题的危害和做法. 也许有时候无意的重题不会被处罚,但我想也应该尽量避免来换取选手的更好体验. Part 0 什么是重题 原题大致可分为完全 ...

  3. Spark的基本原理

    Application Application是在使用spark-submit 提交的打包程序,也就是需要写的代码.完整的Application一般包含以下步骤:(1)获取数据(2)计算逻辑(3)输出 ...

  4. 运维排查 | Systemd 之服务停止后状态为 failed

    哈喽大家好,我是咸鱼. 我们知道 CentOS 7 之后,Systemd 代替了原来的 SystemV 来管理服务,相比 SystemV ,Systemd 能够很好地解决各个服务间的依赖关系,还能让所 ...

  5. #Kruskal重构树,主席树,倍增#洛谷 4197 Peaks

    题目传送门 分析 首先第\(k\)大一般都是主席树 问题是困难值的限制有点束手无措 又是\(\text{Kruskal重构树}\) 将困难值为边权跑最小生成树,重新建树,实际上让困难值跳到尽量大的位置 ...

  6. OpenHarmony集成OCR三方库实现文字提取

    1. 简介 Tesseract(Apache 2.0 License)是一个可以进行图像OCR识别的C++库,可以跨平台运行 .本样例基于Tesseract库进行适配,使其可以运行在OpenAtom ...

  7. OpenHarmony——内核IPC机制数据结构解析

    一.前言 OpenAtom OpenHarmony(以下简称"OpenHarmony")是由开放原子开源基金会(OpenAtom Foundation)孵化及运营的开源项目,目标是 ...

  8. Linux之sudo

    [摘要] 生产环境中为了系统的安全性,Linux主机的root权限是只能管理器使用,普通用户不具有root权限,但是可以通过sudo获取root权限执行一些操作. 一.知识要点 wheel组 在Lin ...

  9. Redis 的并发竞争问题是什么?如何解决这个问题?了解 redis 事务的 CAS 方案吗?

    面试官心理分析 这个也是线上非常常见的一个问题,就是多客户端同时并发写一个 key,可能本来应该先到的数据后到了,导致数据版本错了:或者是多客户端同时获取一个 key,修改值之后再写回去,只要顺序错了 ...

  10. async与await暂停作用

    1. async function Request () { await new Promise(res => { setTimeout(() => { console.log(1) re ...