`
memorymyann
  • 浏览: 266560 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

linux学习二内存管理重要的数据结构

阅读更多

这里只列举几个比较麻烦的数据结构

struct list_head {
    struct list_head *next, *prev;
} //linux通用的双向链队列,下面多处用到,这里列出源代码

linux对内存再用页式管理,对于页,就有个数据结构page加以描述。在内核中有个全局量mem-map指向的是一个page的数组,整个数组描述了整个物理内存,大家注意32位地址线,内存大小是2的32次方。由于页大小是4k也就是2的12次方。每4K的页就有一个page。那么2的32次方共有2的20次方个页,则mem-map指向的数组大小就是2的20次方。其中明显对于页的物理地址,一定是4K的倍数,因为它大小是4K,那么这个数组就有个对应,数组下标后面12个0(2进制)对应了页面的物理地址,他们在数值上是相等的。那么我们在page数据结构中就没有必要存贮它的物理地址。page数据结构定义位置include/linux/mm.h

struct page{

struct list_head list;   //通过使用它进入下面的数据结构free_area_struct结构中的双向链队列

struct address_space * mapping;   //用于内存交换的数据结构

unsigned long index;//当页面进入交换文件后

struct page *next_hash; //自身的指针,这样就可以链接成一个链表

atomic t count; //用于页面交换的计数,若页面为空闲则为0,分配就赋值1,没建立或恢复一次映射就加1,断开映射就减一

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; //指向所属的管理区

}

(对于每个项的说明,我会慢慢补上)

对内存,仅仅用page数据结构来描述肯定远远不够,对于整个内存,我们在此之上分了管理区的概念,每个管理区管理数个页面。这个数据结构是 zone_struct定义位置是在include/linux/mmzone.h

typedef struct free_area_struct {
    struct list_head free_list;   //linux 中通用的双向链队列
    unsigned int * map;
} free_area_t;

typedef struct zone_struct{

    spinlock_t        lock;

    unsigned long offset;  //表示该管理区在mem-map数组中,起始的页号

    unsigned long free pages;
    unsigned long inactive_clean_pages;
    unsigned long inactive_dirty_pages;
    unsigned pages_min, pages_low, pages_high;
   
    struct list_head inactive_clean_list;   //用于页面交换的队列,基于linux页面交换的机制。这里存贮的是不活动“干净”页面
    free_area_t free_area[MAX_ORDER]; 

//一组“空闲区间”队列,free_area_t定义在上面,其中空闲下标表示的是页面大小,例如:数组第一个元素0号,表示所有区间大小为2的0次方的页面链接成的双向队列,1号表示所有2的1次方页面链接链接成的双向队列,2号表示所有2的2次方页面链接成的队列,其中要求是这些页面地址连续
   
    char * name;
    unsigned long size;
   
    struct pglist_data * zone_pgdat;   //用于指向它所属的存贮节点,及下面的数据结构
    unsigned  long  zone_start_paddr;
    unsigned  long    zone_start_mapnr;
    struct page * zone_mem_map;

} zone_t;

我们知道内存的地位并不是“平等的”,例如主内存和图形卡上的静态内存ram就不是“平等地位”,因此我们页面管理机制做了修正,管理区不是内存管理中最高层的概念,前述的page数组mem-map也不是全局,而是从属于具体的节点,在zone_struct 上面有了一层代表存贮节点的数据结构pglist_data,定义于include/linux/mmzone.h 中

typedef struct pglist_data {
    zone_t    node_zones[MAX_NR_ZONES];   //该节点最多的3个页面管理区,MAX_NR_ZONE值是3,在linux中分为3个管理区,也可能是2个ZONE_DMA,ZONE_NORMAL,ZONE_HIGHMEM
    zonelist_t    node_zonelist[NR_GFPINDEX];   //具体说明见下面的数据结构
    struct page * node_mem_map;   //用于指向属于该存储节点的page数组
    unsigned long * valid_addr_bitmap;
    struct bootmem_data    * bdata;
    unsigned long node_start_paddr;
    unsigned long node_start_mapnr;
    unsigned long node_size;
    int    node_id;
    struct pglistdata * node_next;   //用于形成一个单链队列
}    pg_data_t;

typedef struct zonelist_struct {
    zone_t * zones [MAX_NR_ZONES+1]; //指针数组,指向每个具体的页面管理区
    int gfp_mask;
}    zonelist_t; //用于描述内存分配策略的数据结构,比如内存中最小适应法则的分配策略,我们就可以将区放入zones数组中,按照区内空闲页面从小到大的原则,但我们要实现这个法则,我们只需要从头到尾便利这个数组,那么找到第一个大于你要求的页面个数的区就是最小适应区

这些都是用于物理空间管理的,虚拟空间管理由下面的数据结构描述(我刚开始把虚拟空间弄成了虚拟内存,越看越糊涂,虚拟空间指的是,在linux中,4G内存被分为2块,搞地址1G内存叫系统空间,所有进程共享,下面的3G便是虚拟空间,每个进程都占有虚拟空间3G,在进程自己看来是这样的,但实际上,他远远没这么多内存用),vm_area_struct数据结构,定义于 include/linux/mm.h,进程虚存空间的描述,他被进一步组织到mm_struct中,它描述是地址连续的空间

struct vm_area_struct {
    struct mm_struct * vm_mm;   //下面说明
    unsigned long  vm_start;
    unsigned long vm_end;   //start和end决定了虚存空间,个人理解应该是mem-map表的下标,其中 start包含,end不包含,同时区间划分不单单是地址连续,还要保证权限的统一
   
    struct vm_area_struct * vm_next;   //将属于同一进程的虚存区间按照虚存地址高低链接起来
   
    pgrot t_vm_page_prot;
    unsigned long vm_flags;   //存贮该区间的权限
   
    short vm_avl_height;
    struct vm_area_struct * vm_avl_left;
    struct vm_area_struct * vm_avl_rigth; //用于生成 avl树,提高搜索效率
   
    struct vm_area_struct * vm_next_share;
    struct vm_area_struct ** vm_pprev_share;
   
    struct vm_operations_struct * vm_ops;   //下面说明
    unsigned long vm_pgoff;
   
    struct file * vm_file;
    unsigned long vm_raend;
    void * vm_private_data;   //这些属性都是用于记录页面与文件关系,具体情况具体分析
}

定义于include/linux/mm.h

struct vm_operations_struct {
    void (*open) (struct vm_area_struct * area);
    void (*close) (struct vm_area_struct * area);
    struct page * (*nopage)(struct vm_area_struct *area, unsigned long address, int write_access);
} //open, close,nopage用于虚存空间打开,关闭和建立印射

 

定义于include/linux/sched.h,进程所有的虚存空间的数据结构描述

struct mm_struct{
    struct vm_area_struct * mmap;   //建立虚存空间的单链队列
    struct vm_area_struct * mmap_avl;   //建立虚存空间的AVL树
    struct vm_area_struct * mmap_cache;   //最近一次使用的虚存空间,由于内存访问总是带有局部性,命中率有35%
    pgd_t * pgd;   //指向进程页面目录,在载入进程时候这个值会被载入到cr3寄存器中
    atomic_t mm_users;
    atomic_t mm_count;
    //这2个变量比较令人费解,mm_users记录是虚存空间的使用者,而mm_count记录的是mm_struct使用的计数。首先虚存空间是可以多个进程使用的,比如如果父进程调用vfork创建子线程,此时2者使用的是同一个虚存空间。线程是没有自己的虚存空间。其次一个mm_struct对应一个虚存,有几个使用者那么就有几个进程通过指针共享了这个mm_struct,按理说这2个计数应该是一个,不应该分成2个。大部分可能性2者是相同的。但又特殊情况,比如内核线程是没有虚存空间,他是需要暂借调用者的虚存空间,只是虚存空间使用者和mm_struct使用计数就不统一
    int map_count;
    struct semaphore mmap_sem;   //用于进程的间的互斥访问
    spinlock_t page_table_lock;
   
    struct list_head mmlist;
   
    unsigned long start_code, end_code, start_data, end_data
    unsigned long start_brk, brk, start_stack;
    unsigned long arg_start, arg_end, env_start, env_end;
    unsigned long rss, total_vm, locked_vm;
    unsigned long def_flags;
    unsigned long cpu_vm_mask;
    unsigned long swap_cnt;
    unsigned long swap_address;
    mm_context_t context;
}

在操作系统中,有个进程控制块(PCB)的概念,具体到linux里面对应的数据结构是task_struct,它内部就有个mm_struct指针,mm_struct是整个用户空间的抽象。待续。。。

分享到:
评论

相关推荐

    关于学习笔记整理,包括Linux、Java、数据结构和算法,和一些IT工具的使用.zip

    Java是一种高性能、跨平台的面向...自动内存管理(垃圾回收): Java具有自动内存管理机制,通过垃圾回收器自动回收不再使用的对象,使得开发者不需要手动管理内存,减轻了程序员的负担,同时也减少了内存泄漏的风险。

    深入理解LINUX内核(第三版)

    , 《深入理解Linux内核,第三版》指导你对内核中使用的最重要的数据结构、算法和程序设计诀窍进行一次遍历。通过对表面特性的探究,作者给那些想知道自己机器工作原理的人提供了颇有价值的见解。书中讨论了Intel特有...

    linux内核设计与实现学习总结

    学习了《Linux内核设计与实现》,基于书本内容,结合Linux源码,并进行实际开发,完成了大数库和ECC向Linux内核的移植,并形成本总结,涵盖原书知识点,并增加了自己的理解,尤其对对VFS和块I/O增加了多张数据结构...

    深入理解Linux内核

    为了彻底理解是什么使得Linux...你将学习到哪些情况下Linux性能最佳,并且你将看到,在大量的不同环境里进行进程调度、文件存取和内存管理时,它如何满足提供良好的系统响应的需要。这本书将帮助你充分利用Linux系统。

    深入理解linux内核

    为了彻底理解是什么使得Linux...你将学习到哪些情况下Linux性能最佳,并且你将看到,在大量的不同环境里进行进程调度、文件存取和内存管理时,它如何满足提供良好的系统响应的需要。这本书将帮助你充分利用Linux系统。

    12本精彩的Linux书籍

    这本书介绍了内核的内存管理,进程调度, I/O架构以及块设备管理等内容。这本书是为那些想深入了解Linux的Geek们而量身打造的。 9. HULinux CookbookUH,作者Carla Schroder。这本书分别以用户和管理员的角度阐释...

    Linux内核工作原理 word版本 强烈推荐

    内存管理这章描叙了Linux如何处理物理内存以及虚拟存储技术。 进程管理描叙了进程的概念以及Linux核心是如何创建、管理与删除系统中的进程。 进程间及进程与核心间通讯以协调它们的活动。Linux支持大量进程间通讯...

    计算机专业主要学习哪些课程.docx

    如果不懂操作系统,你在未来学习编程语言的高级特效,涉及到线程进程调度,内存分配,或者是学习 Linux 相关的知识时,都会一头雾水,所以,只有学会了操作系统,我么才能够更好地学习其他语言和技术。 基于此,...

    Linux程序设计 第4版.haozip01

    7.1 内存管理 214 7.1.1 简单的内存分配 214 7.1.2 分配大量的内存 215 7.1.3 滥用内存 218 7.1.4 空指针 219 7.1.5 释放内存 220 7.1.6 其他内存分配函数 221 7.2 文件锁定 222 7.2.1 创建锁文件 222 ...

    入门学习Linux常用必会60个命令实例详解doc/txt

    要想真正理解Linux系统,就必须从Linux命令学起,通过基础的命令学习可以进一步理解Linux系统。 不同Linux发行版的命令数量不一样,但Linux发行版本最少的命令也有200多个。这里笔者把比较重要和使用频率最多的命令...

    关于嵌入式Linux系统开发学习流程详解

     二:Linux基础 Linux操作系统的概念、安装方法,详细了解Linux下的目录结构、基本命令、编辑器VI ,编译器GCC,调试器GDB和 Make 项目管理工具, Shell Makefile脚本编写等知识,嵌入式开发环境的搭建。...

    Linux程序设计 第4版.haozip02

    7.1 内存管理 214 7.1.1 简单的内存分配 214 7.1.2 分配大量的内存 215 7.1.3 滥用内存 218 7.1.4 空指针 219 7.1.5 释放内存 220 7.1.6 其他内存分配函数 221 7.2 文件锁定 222 7.2.1 创建锁文件 222 ...

    涵盖C++ Primer 5th、 effective C++ 、 STL api和demos C++ 基础知识与理论等

    涵盖C++ Primer 5th、 effective C++ 、 STL api和demos C++ 基础知识与理论、 智能指针、C++11、 Git教程 Linux命令 Unix操作系统(进程、线程、内存管理、信号)计算机网络、 数据结构(排序、查找)、数据库、、...

    Linux操作系统基础教程

    一.Linux的文件系统结构.....................................................................................................6 二. 文件类型................................................................

    Linux内核注释

    作者分析了核心代码,并对重要的函数、系统调用和数据结构提供了大量的注释。 对《注释》系列丛书的写作灵感都来源于John Lions所著的大量流行的《Lions' Commentary on Unix》一书。无数的计算机专业的学生在复制...

    基于QT、ARM开发板、Linux系统并对接百度AI的停车管理系统.zip

    ① 在要对文件进行加密解密的时候,先将文件按一定的数据结构读入内存,然后进行加密或解密操作。运算数据都读取自内存。 ② 在对加密或解密完成的数据进行写出的时候,都是将其直接写到指定好的文件,即直接写入...

    自制OS雏形

    学习linux 2.4.0内核的小成果,里面借鉴了很多linux中的数据结构、函数、代码、原理等,并非原创。自己在xp上用vc和masm将内核启动的一小部分实现出来。引导,中断,启动内存管理,页表设置等内容, 都已经完成。...

    学习《深入理解程序设计 使用Linux汇编语言》的代码.zip

    - **教学与理解计算机原理**:学习汇编语言有助于深入理解计算机体系结构、指令集、内存管理和硬件接口等基础概念。 ### 编程特点与挑战 - **手动管理内存**:程序员需要手动分配和释放内存,跟踪数据在内存中的...

Global site tag (gtag.js) - Google Analytics