linux内存管理详解,linux内存管理分析【一】

1 内存管理相关结构

1.1 内存结点

计算机按管理物理内存的不同方法分为两类:

UMA计算机:(一致内存访问)将内存以连续方式组织起来,多处理器系统中每 个处理器访问各个内存区都是同样快。

NUMA计算机:(非一致内存访问)每个处理器都有本地内存,可快速访问。各 个处理器通过总线连接起来,以支持对其他处理器的访问,访问速度比访问本地内存慢些。

这两种计算机模型可以混用,比如在UMA计算机上,如果内存不连续使用NUMA模型管理会更有帮助。这两种模型在算法上没有什么差别,在UMA系统上,只使用一个NUMA节点来管理内存,内存管理的其他部分认为它在处理一个伪NUMA系统。

内存结点管理结构如下:

include/linux/mmzone.h

typedef struct pglist_data {

struct zone node_zones[MAX_NR_ZONES];//结点中包含的所有内存域

备用结点内存域列表,在当前结点中没有内存分配时可到备用节点中分配。

struct zonelist node_zonelists[MAX_ZONELISTS];

int nr_zones;节点中内存域的数目

#ifdef CONFIG_FLAT_NODE_MEM_MAP /* means !SPARSEMEM */

struct page *node_mem_map;指向页结构的数组,该数组包含了节点中所有域的页

......

#ifndef CONFIG_NO_BOOTMEM

系统启动时会启用一套临时内存管理机制,struct bootmem_data就是该机制的管理结构

struct bootmem_data *bdata;

#endif

......

node_start_pfn表示节点中第一个页帧编号。页帧的编号是全局统一的,在UMA系统中只有一个节点所以node_start_pfn为0.

unsigned long node_start_pfn;

unsigned long node_present_pages;结点中页帧的总数

unsigned long node_spanned_pages; 结点中包括空洞在内的页帧总数

int node_id;结点的编号

wait_queue_head_t kswapd_wait;交换进程的等待队列

struct task_struct *kswapd; 指向负责该结点的交换进程的task_struct 结构

int kswapd_max_order; 由页交换子系统使用,定义要释放的区域大小。

enum zone_type classzone_idx;

} pg_data_t;

1.2 内存域

系统中所有内存域类型由一个枚举结构来管理:

include/linux/mmzone.h

enum zone_type {

#ifdef CONFIG_ZONE_DMA

ZONE_DMA, 适用于DMA的内存域

#endif

#ifdef CONFIG_ZONE_DMA32

使用32位寻址的适用于DMA的内存域,只有在64为系统中才与ZONE_DMA有差别

ZONE_DMA32,

#endif

ZONE_NORMAL,可直接映射到内核段的普通内存域

#ifdef CONFIG_HIGHMEM

ZONE_HIGHMEM,超出了内核段的物理内存

#endif

ZONE_MOVABLE,伪内存域,防止物理内存碎片机制中要使用该内存域

__MAX_NR_ZONES 可能有的内存域的总数

};

内存域管理结构struct zone在文件include/linux/mmzone.h中定义,如下:

struct zone {

数组watermark管理该内存域的三个水线值:

WMARK_HIGH:空闲页多余该值表示内存域的状态是理想的

WMARK_LOW:空闲页低于该值,内核开始将页换出到磁盘

WMARK_MIN:空闲页低于该值,急需空闲页,内存紧张

unsigned long watermark[NR_WMARK];

当空闲页低于该值,采取一些方法计算空闲页的总数,避免内存漂移导致水线值失效

unsigned long percpu_drift_mark;

保留一些空闲页,用于一些无论如何都不会失败的关键性分配

unsigned long           lowmem_reserve[MAX_NR_ZONES];

unsigned long           dirty_balance_reserve;

#ifdef CONFIG_NUMA

int node;  所属的NUMA节点

当可回收的页超过此值时,将进行页面回收。

unsigned long           min_unmapped_pages;当

内存管理区中,用于slab的可回收页大于此值时,将回收slab中的缓存页。

unsigned long           min_slab_pages;

#endif

每CPU的页面缓存, 当分配单个页面时,首先从该缓存中分配页面,可提高效率

struct per_cpu_pageset __percpu *pageset;

该锁用于保护伙伴系统数据结构。即保护free_area相关数据。

spinlock_t              lock;

当管理区中的所有页面都不可回收时设置此标志

int                     all_unreclaimable;

......

用于实现伙伴系统。这个数组定义了11个队列,每个队列中的元素都是大小为2^n的页面块。

struct free_area        free_area[MAX_ORDER];

......

#ifdef CONFIG_COMPACTION

下面字段用于内存紧缩。

unsigned int            compact_considered;

unsigned int            compact_defer_shift;

int                     compact_order_failed;

#endif

ZONE_PADDING(_pad1_)确保后面的字段是缓存行对齐的

下面几个字段都跟页面回收相关

spinlock_t              lru_lock;

struct lruvec           lruvec;

unsigned long           pages_scanned;     /* since last reclaim */

unsigned long           flags;             /* zone flags, see below */

该内存区域中的各种统计信息,

atomic_long_t           vm_stat[NR_VM_ZONE_STAT_ITEMS];

unsigned int inactive_ratio;

ZONE_PADDING(_pad2_)

等待队列,用于等待该区域内存的进程

wait_queue_head_t       * wait_table;

unsigned long           wait_table_hash_nr_entries;

unsigned long           wait_table_bits;

struct pglist_data      *zone_pgdat;指向该区域所属的结点

unsigned long           zone_start_pfn;该区域的起始页帧号

unsigned long           spanned_pages; 该区中包含空洞在内,总的页帧数

unsigned long           present_pages; 总的页帧数,不包含空洞

const char              *name;该区域的名字,如Normal、DMA、Highmem等

} ____cacheline_internodealigned_in_smp;

1.3 页面

系统中每个物理页面都有一个相关联的page结构用于记录该页面的状态

include/linux/mm_types.h

struct page {

页面标志,也包含了一些其他信息,比如页面所处的管理区编号等

unsigned long flags;

如果最低位为0,则指向inode 的address_space,或则为NULL。如果页映射为匿名内存,最低位置位,而且该指针指向anon_vma对象

struct address_space *mapping;

......

struct {

union {

表示在也表中有多少项指向该页

atomic_t _mapcount;

用于slub

struct {

unsigned inuse:16;

unsigned objects:15;

unsigned frozen:1;

};

};

页的使用计数

atomic_t _count;

};

};

};

......

union {

指向私有数据的指针,虚拟内存管理会忽略该数据。根据页的用途,可以用不同的方式使用该指针。

unsigned long private;

......

用于SLUB分配器,指向slab的指针

struct kmem_cache *slab;

用于复合页,指向首页

struct page *first_page;

};

用于高端内存区中的页,即无法直接映射到内核内存中的页。Virtual用于存储该页的虚拟地址。

void *virtual;

......

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值