zoukankan      html  css  js  c++  java
  • Linux内核设计基础(五)之内存管理

    我感觉学习操作系统首先要从内存分配和管理入手。

    首先我们应该知道现代操作系统是以页为单位进行内存管理的,32位体系结构支持4KB的页。而64位体系结构支持8KB的页。页是用来分配的。怎样才干进行高效和充分的利用。这是内存管理单元(MMU)应当细致考虑的。


    页分配

    内核用结构体struct page表示每一个物理页。内核用这一结构来管理系统中全部的页,由于内核须要知道一个页是否空暇(也就是页有没有被分配)。假设页已经被分配,内核须要知道谁拥有这个页,拥有者可能是用户空间进程、动态分配的内核数据、静态内核代码或页快速缓存。我们用页表来统一管理全部的struct page。另外内核用区对具有相似特性的页进行分组。

    主要是存在以下两种制约:

    • 一些硬件仅仅能用某些特定的内存地址运行DMA(直接内存訪问)
    • 一些体系结构的内存的物理寻址范围比虚拟寻址范围大得多。

      这样,就有一些内存不能永久地映射到内核空间(高端内存)

    于是Linux划分了一下四个区:
    • ZONE_DMA——这个区包括的页能用来运行DMA操作。
    • ZONE_DMA32——同上,只是仅仅能被32位设备訪问。
    • ZONE_NORMAL——这个区包括的都是能正常映射的页。
    • ZONE_HIGHEM——高端内存,当中的页并不能永久映射到内核地址空间。


    slab层

    用于频繁使用的数据结构的缓存。且避免因频繁分配和使用导致的内存碎片。slab层是由快速缓存组成的,而每一个快速缓存能够由多个slab组成,slab由一个或多个物理上连续的页组成。每一个slab都包括一些缓存的数据结构。这样说还是非常抽象,举个inode的样例。

    inode是磁盘文件在内存中的体现,会频繁地进行创建和释放,所以有必要进行缓存管理。在这里快速缓存是inode_cachep。它由多个slab组成,而每一个slab包括尽可能多的struct inode对象。

    所以当我们须要一个新的inode结构时,不必现创建,仅仅需从部分满或空的slab返回一个指向已分配但未使用的inode结构的指针就可以。当内核使用完这个inode对象时。slab分配器就把该对象标记为空暇,留给后来者。

    再举个进程控制块的样例。

    我们知道进程在不停地创建和消除,而用struct task_struct去管理一个进程。不停的创建和释放task_struct会非常费时。所以内核初始化期间,在fork_init()中着手创建快速缓存:

    struct kmem_cache *task_struct_cachep;(内核用这个全局变量存放指向task_struct快速缓存的指针)
    task_struct_cachep = kmem_cache_create("task_struct",
                                            sizeof(struct task_struct),
                                            ARCH_MIN_TASKALIGN,
                                            SLAB_PANIC | SLAB_NOTRACK,
                                            NULL);

    这样当我们创建进程(运行fork)时,仅仅需从这个快速缓存中索取就可以:

    struct task_struct *tsk;
    tsk = kmem_cache_alloc(task_struct_cachep, GFP_KERNEL);
    if(!tsk) return NULL;

    内核栈

    我们在进程时要注意节省栈资源。要控制函数内的局部变量。尽量不要出现大型数组或大型结构体。尤其对于内核栈,一旦造成溢出,就会影响到内核数据(如thread_info)。所以应当优先考虑动态分配。另外一个进程的内核栈和中断栈是分开的,这样能够减轻内核栈的负担(一个内核栈仅仅占1页或2页)。




  • 相关阅读:
    打印杨辉三角
    插值排序
    各种冒泡排序法
    Linux系统命令符01
    2.1博客系统 |基于form组件和Ajax实现注册登录
    python面试笔试题,你都会了吗?快来复习
    1.2博客系统 |登录页| 验证码
    1.1博客系统| 表结构
    第五章:5.2面向对象-绑定方法和非绑定方法| 内置方法 |元类
    11.Django|中间件
  • 原文地址:https://www.cnblogs.com/lytwajue/p/7263450.html
Copyright © 2011-2022 走看看