[Linux内存]linux内存学习(三)——内存管理基础
2015-01-26 19:53
260 查看
1,linux内核内存管理
arm体系结构的内存建立是在
kernel/arch/arm/kernel/setup.c文件里~
linux内核设计与实现——内存管理
linux内核中,内核把物理页作为内存管理的基本单元,处理器最小的寻址单位是字节,从虚拟内存角度看,页是最小单位。
内核中使用struct page结构来表示每个物理页,系统中每个物理页都有这样的一个结构体。所有的页描述符存在mem_map数组中,每个页描述符(struct page)长度为32字节。
[cpp] view plaincopy
typedef struct page {
struct list_head list;
struct address_space *mapping;
unsigned long index;
struct page *next_hash;
atomic_t count;
unsigned long flags;
struct list_head lru;
unsigned long age;
wait_queue_head_t wait;
struct page **pprev_hash;
struct buffer_head * buffers;
void *virtual;
struct zone_struct *zone;
} mem_map_t;
Linux提供page_zone()函数用来接收一个页描述符的地址作为它的参数;它读取该描述符中的flags字段的最高位,然后通过查看zone_table数组来确定相应管理区描述符的地址
所有的页描述符存放在全局mem_map数组中,其数组的下标为页框号(pfn)页描述符与页框的映射
virt_to_page(addr):线性地址addr对应的页描述符地址
pfn_to_page(pfn):页框号pfn对应的页描述符地址
page_to_pfn(pg): 页描述符对应的页的页框号pfn
内核页划分为不同的区,linux主要有四种区
ZONE_DMA 用来执行DMA相关操作
ZONE_NORMAL 能正常映射的页
ZONE_HIGHEM 高端内存
ZONE_DMA,ZONE_NORMAL,ZONE_HIGHEM是针对物理页来划分的。
每个区使用了struct zone结构体来表示
▪Linux提供page_zone()函数用来接收一个页描述符的地址作为它的参数;它读取该描述符中的flags字段的最高位,然后通过查看zone_table数组来确定相应管理区描述符的地址
kmalloc()函数和vmalloc()函数的区别:
kmalloc()函数分配的内存是物理上连续的,而Vmalloc()函数分配的内存仅仅是虚拟地址连续的,正常内核编程通常使用kmalloc(),这主要是处于性能的考虑,因为vmalloc()将物理不连续的页转换为虚拟地址空间上连续的页,必须专门建立页表项,vmalloc()仅仅在当需要使用大块的内存的时候才会使用,典型的如模块被动态插入内核的时候。另外很多硬件设备需要的是物理地址连续的页,因为很多硬件设备存在于内存管理单元(MMU)之外。另外vmalloc()函数可能睡眠,不能在中端上下文使用,而kmalloc加GFP_ATOMIC可以保证用在不能睡眠的地方
保留的页框池
当在处理中断或者执行临界区内的代码的时候,代码申请内存的时候不能被阻塞,如果当前内存空闲的内存不够,那么直接返回失败,为了尽量减少失败的次数,内核为原子内存分配请求保留了一个页框池,最下为128K,最大为65536KB(为关键分配保留的最小值)
2,UMA和NUMA
UMA:一致内存访问,系统中每个处理器访问各个内存区都是同样块
NUMA:非一致内存访问,系统中各个CPU都有自己的本地内存,各个处理器通过总线连接起来,以支持对其他cpu的本地内粗访问
(N)UMA中的内存模型
在NUMA上内存划分为节点,每个节点关联到一个处理器,各个节点通过单链表的形式组织,UMA上只有一个节点,节点用struct pg_data_t结构体表示,各个节点又分为内存区域,区域通过结构体struct zone表示,区域有ZONE_DMA,ZONE_NORMAL,ZONE_GIGHMEM等,各个内存区域关联到一个数组,用来管理属于该内存区域的物理页,对于每个物理页,使用struct page结构体表示。
3,内存域水印
内存水印由struct zone结构体中的pages_min,pages_high,pages_low表示,如果空闲页多于pages_high,则内存域的状态是理想的,如何内存页的数量低于pages_low,则内核开始将页换出到硬盘,
4,冷热页
struct zone结构体中的pageset成员用于实现冷热分配器,内核说页是热的意味着页已经加载到CPU的高速缓存,冷页不在高速缓存中,每个cpu都有自己的冷热页数组。
arm体系结构的内存建立是在
kernel/arch/arm/kernel/setup.c文件里~
linux内核设计与实现——内存管理
linux内核中,内核把物理页作为内存管理的基本单元,处理器最小的寻址单位是字节,从虚拟内存角度看,页是最小单位。
内核中使用struct page结构来表示每个物理页,系统中每个物理页都有这样的一个结构体。所有的页描述符存在mem_map数组中,每个页描述符(struct page)长度为32字节。
[cpp] view plaincopy
typedef struct page {
struct list_head list;
struct address_space *mapping;
unsigned long index;
struct page *next_hash;
atomic_t count;
unsigned long flags;
struct list_head lru;
unsigned long age;
wait_queue_head_t wait;
struct page **pprev_hash;
struct buffer_head * buffers;
void *virtual;
struct zone_struct *zone;
} mem_map_t;
Linux提供page_zone()函数用来接收一个页描述符的地址作为它的参数;它读取该描述符中的flags字段的最高位,然后通过查看zone_table数组来确定相应管理区描述符的地址
所有的页描述符存放在全局mem_map数组中,其数组的下标为页框号(pfn)页描述符与页框的映射
virt_to_page(addr):线性地址addr对应的页描述符地址
pfn_to_page(pfn):页框号pfn对应的页描述符地址
page_to_pfn(pg): 页描述符对应的页的页框号pfn
内核页划分为不同的区,linux主要有四种区
ZONE_DMA 用来执行DMA相关操作
ZONE_NORMAL 能正常映射的页
ZONE_HIGHEM 高端内存
ZONE_DMA,ZONE_NORMAL,ZONE_HIGHEM是针对物理页来划分的。
每个区使用了struct zone结构体来表示
▪Linux提供page_zone()函数用来接收一个页描述符的地址作为它的参数;它读取该描述符中的flags字段的最高位,然后通过查看zone_table数组来确定相应管理区描述符的地址
kmalloc()函数和vmalloc()函数的区别:
kmalloc()函数分配的内存是物理上连续的,而Vmalloc()函数分配的内存仅仅是虚拟地址连续的,正常内核编程通常使用kmalloc(),这主要是处于性能的考虑,因为vmalloc()将物理不连续的页转换为虚拟地址空间上连续的页,必须专门建立页表项,vmalloc()仅仅在当需要使用大块的内存的时候才会使用,典型的如模块被动态插入内核的时候。另外很多硬件设备需要的是物理地址连续的页,因为很多硬件设备存在于内存管理单元(MMU)之外。另外vmalloc()函数可能睡眠,不能在中端上下文使用,而kmalloc加GFP_ATOMIC可以保证用在不能睡眠的地方
保留的页框池
当在处理中断或者执行临界区内的代码的时候,代码申请内存的时候不能被阻塞,如果当前内存空闲的内存不够,那么直接返回失败,为了尽量减少失败的次数,内核为原子内存分配请求保留了一个页框池,最下为128K,最大为65536KB(为关键分配保留的最小值)
2,UMA和NUMA
UMA:一致内存访问,系统中每个处理器访问各个内存区都是同样块
NUMA:非一致内存访问,系统中各个CPU都有自己的本地内存,各个处理器通过总线连接起来,以支持对其他cpu的本地内粗访问
(N)UMA中的内存模型
在NUMA上内存划分为节点,每个节点关联到一个处理器,各个节点通过单链表的形式组织,UMA上只有一个节点,节点用struct pg_data_t结构体表示,各个节点又分为内存区域,区域通过结构体struct zone表示,区域有ZONE_DMA,ZONE_NORMAL,ZONE_GIGHMEM等,各个内存区域关联到一个数组,用来管理属于该内存区域的物理页,对于每个物理页,使用struct page结构体表示。
3,内存域水印
内存水印由struct zone结构体中的pages_min,pages_high,pages_low表示,如果空闲页多于pages_high,则内存域的状态是理想的,如何内存页的数量低于pages_low,则内核开始将页换出到硬盘,
4,冷热页
struct zone结构体中的pageset成员用于实现冷热分配器,内核说页是热的意味着页已经加载到CPU的高速缓存,冷页不在高速缓存中,每个cpu都有自己的冷热页数组。
相关文章推荐
- [Linux内存]linux内存学习(三)——内存管理基础
- Linux内存管理和性能学习笔记(一):内存测量与堆内存
- linux基础学习第0章笔记(二)--广义内存
- OC基础:内存(内存管理) 分类: ios学习 OC 2015-06-25 16:50 73人阅读 评论(0) 收藏
- Linux内存管理和性能学习笔记(一):内存测量与堆内存
- 【Linux基础系列之】内存管理(2)-高端内存
- arm-linux内存管理学习笔记(1)-内存页表的硬件原理
- Linux内存管理学习笔记——内存寻址
- arm-linux内存管理学习笔记(1)-内存页表的硬件原理
- 个人学习笔记---Linux内存:内存管理的实质
- Linux内存管理学习笔记——内存寻址
- Linux设备驱动程序——内存和I/O基础知识学习:(1)内核中相关基础知识学习
- Linux基础学习之测硬盘读写速度、内存读写速度的一种方法
- 转: C++动态内存创建与内存管理学习笔记[3]
- Linux设备驱动程序学习(8)-分配内存
- Linux基础命令小结(下)- Linux学习日记
- LINUX 学习之基础一 基本命令学习
- Linux编程C++内存管理之内存分配详解
- Linux基础 学习笔记
- 《深入理解LINUX内存管理》学习笔记 (三)