`
cocos
  • 浏览: 400302 次
  • 性别: Icon_minigender_1
  • 来自: 福州
社区版块
存档分类
最新评论

内存管理机制

阅读更多

内存管理是一个操作系统必不可少 . 并且 . 非常重要的一环 .linux 的成功 . 和它优秀的内存管理联系非常密切 . 因为一个系统的高效性欲稳定性往往决定于它的内存管理机制 . 我项很多人吃过 dos 640k 的苦吧 .

前面我们介绍了 386 保护模式 . 从今天起我们将在此基础上 , 分析 linux 的虚拟存储管理 , 对每个程序员来说 . 他们都希望有无穷大的快速的内存 , 然而 , 现阶段是不可能的 , 况且 , 无穷大与快速本身就可能矛盾

为了解决无穷大 .linux 引入了虚拟存储系统 , 为了解决快速 ,linux 引入了 cache , 交换机制等等 , 以使的存储系统 , 在容量上接近硬盘 , 速度上接近 cache.( 当然 , 我认为这是存储系统的实际目的 ).

Linux 的内存管理采取的是分页机制 . 它的设计目的是分时多任务 .linux 可同时处理 256 个任务 ( 这应该与某个变量来定义 , 一时想不起来 ). 同时它采用了两级饱和机制来分别内核进程与用户进程 .

386 保护模式的 0-4G 的线性虚拟地址中 ,3-4G 是留给内核进程的 . 0-3G 分给用户进程 . 内核在内核空间的寻址不同于用户进程在用户空间的寻址 . 因为内核是在启动时装入内存的 . 说以它可以直接吧地址映射到 3G 以上 . 用户若想访问内核就不许通过 swapper_pg_div 中的指针来得到页表 .

相反 , 用户进程 , 在用户空间的寻址是通过所用户页目录中的指针得到用户的页表 . 并通过页表的指针直接指向相应的物理内存 .

Linux 虚拟内存的实现 , 需要几种不同的机制来实现 :

地址映射机制

内存的分配与回收

请页机制

交换机制

内存共享机制

在具体的读源码之前 . 我们先根据我们以前学过的操作系统知识 . C 语言等知识 . 来考虑一下 , 这几个机制如何实现 . 现自己设计一下 . 在看别人是怎样实现的 . 找到自己想不到 . 或者对效率空间有损的地方 . 这样才有进步 . 我不止一次的说 . 操作系统的某一部分 , 就起实现来说 , 非常简单 . 它的难点是如何将大量的功能集成出一个 kernerl.

地址映射机制 , 说白了 , 就是在虚拟内存与物理内存上的一个桥梁 . 它要做的事情可能就是通过几个不同的表 . 把虚拟地址转换成物理地址 , 把物理地址转化虚拟地址 .

我们以前说过 . 因为有系统与用户之分 , 它必须也要有不同的数据结构 . 为了解决速度等问题 . 它会有一个硬件的缓冲区

对于它的数据结构 . 我们可以先想一下 . 如虚拟地址的信息 , 虚拟地址在那个区域等等

至于请页机制 , 更好理解 . 因为 linux 是页式存储的 . 因此必然会存在空白页和使用页 . 既然是页 . 就必然会存在页溢出 . 页无效 ( 是不是在 win98 下经常出现类似错误 , 当然 linux 的内存管理不可能和 windows 一样 , 可基本道理相同 ). 因此 . 在每一个页出错 . 或者该页存不下多余的数据时 . 就要要求内核分配新的页面

同时 . 当时用 fork() 产生一个新的进程时 . 也需要分配新的叶面 . 这一部分大概讲的就是进程如何向内和描述自己需要怎么样的和多少页

在我们学习 << 数据结构 >> 是我们学了 , 很多内存分配方式 , 如首次拟和 . 最佳拟和 , 最差拟和等等 . 但是我们可以想象 .linux 大概不会用他们 . 那就一定是伙伴系统了 . 因此我们可以对于伙伴系统的分配 , 回收的基本算法 . 回想一下 . 这样在读者一部分源码时 , 回有意象不到的收获 .

至于交换机制 . 我们也可以现想一想 . 内存中总与很多使用者的页 . 如果这些也已经把所有的页都用完了 . 再分配时必须把其中的某些页释放 . 释放那些页 , 需要考虑 . 如最近不用页 . 近期少用页 , 等等都可以在考虑之中 .

这个算法 , 大概就是计算内存中使用的页 , 什么时候可以换处 . 说白了就是为所有的使用页计算一个 ”, 而这个 就决定了他什么时候被释放以换如它的内容 . 需要想的是对于经常使用的页 . 可以把它放入 cahe.( 尽管这一部分对程序员是透明的 , 但我们应该理解他的原理 ).

最后的一部分共享内存 , 我想和我门初学 linux 编程时 , 进程通讯里面的共享内存没有区别 . 大概也就是在它的数据结构中加入可以允许不同进程访问的 tag 就行了 .

以上 , 只是我们对 linux 的内存管理机制的猜测 , 需要我们做的工作就是具体的读源码 . 更正不正确的猜想 . 同时学习别人的实际思路 .

从下篇日记开始 . 我们将分别讲解这几部分的实现

 

地址的映射机制

地址的映射机制 , 主要完成主存 . 辅存 . 和虚存之间的关联 . 包括磁盘文件到虚存的映射和虚存与内存的映射关系 . 为了虚拟存储和进程调度相一致 .linux 采用可一系列的数据结构 , 和一个硬件缓存 (TLB) 来实现地址映射机制 .

mm_strut 用来描述进程的缓存 .

struct mm_struct

{

struct vm_area_struct * mmap; /* list of VMAs */

struct vm_area_struct * mmap_avl; /* tree of VMAs */

struct vm_area_struct * mmap_cache; /* last find_vma result */

pgd_t * pgd;

atomic_t count;

int map_count; /* number of VMAs */

struct semaphore mmap_sem;

spinlock_t page_table_lock;

unsigned long context;

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; /* number of pages to swap on next pass */

unsigned long swap_address;

/*

* This is an architecture-specific pointer: the portable

* part of Linux does not know about any segments.

*/

void * segments;

};

他描述了一个进程的页目录 , 有关进程的上下文信息 . 以及数据 . 代码 . 堆栈的启示结束地址 . 还有虚拟存储取得数目 . 以及调度存储用的链表指针 . 他的参差比较高

较高层次的 vm_area-struct 是描述进程的虚拟地址区域 . 他形成一个算相链表 . 按虚地址下降排列 . 这样当内核需要在一个给定进程页上执行给定操作时 . 客从双向列表中找到该项 . 在世想有关页的处理 . . 页错误 . 页换出等等

他的具体结构如下 :

struct vm_area_struct {

struct mm_struct * vm_mm; /* VM area parameters */

unsigned long vm_start;

unsigned long vm_end;

 

/* linked list of VM areas per task, sorted by address */

struct vm_area_struct *vm_next;

 

pgprot_t vm_page_prot;

unsigned short vm_flags;

 

/* AVL tree of VM areas per task, sorted by address */

short vm_avl_height;

struct vm_area_struct * vm_avl_left;

struct vm_area_struct * vm_avl_right;

 

/* For areas with inode, the list inode->i_mmap, for shm areas,

* the list of attaches, otherwise unused.

*/

struct vm_area_struct *vm_next_share;

struct vm_area_struct **vm_pprev_share;

 

struct vm_operations_struct * vm_ops;

unsigned long vm_offset;

struct file * vm_file;

unsigned long vm_pte; /* shared mem */

};

page 结构 则是对物理页进行描述的一个数据结构 , 他不是一个真正的物理页 . 而只不过是描述了一个物理页的内容和框架 . 作了逻辑页的一个标志 ;. 他的标志域定义了这个页在进行的操作 . 链域则定义了一个双项链表 . 时的页框 . 可以很容易的查找到 . 为实际物理内存的使用直到方便

他的具体结构如下

typedef struct page {

/* these must be first (free area handling) */

struct page *next;

struct page *prev;

struct inode *inode;

unsigned long offset;

struct page *next_hash;

atomic_t count;

unsigned long flags; /* atomic flags, some possibly updated asynchronously */

wait_queue_head_t wait;

struct page **pprev_hash;

struct buffer_head * buffers;

int owner; /* temporary debugging check */

} mem_map_t;

所有的 page 结构将都被转入一个叫做 mem_map 的数组中 .

当一个进程运行时 , 他的代码段和数据段将都会被调入内存 . 如果它使用了共享库 . 共享客的内容也将贝雕如内存 . 进程运行时 . 系统首先分配一个 vm_area_struct 给进程 . 并将这各进程连结到虚拟内存的连标中去 . 这是根据进程的可执行影像中的信息 . 吧数据段和客执行代码非配内存 . 新分配的内存必须和进程已有的内存连结起来才能应用 . 这样聚会出现页故障 . 系统利用了请页机制来避免对物理内存的过分使用 . 但进程访问的虚存不在当前的物理内存时 , 这时系统会将需要的页调入内存 . 同时修改进程的页表 . 用来标志虚拟页是否在物理内存中 .

因此 , 系统用了较复杂的数据结构来跟踪进程的虚拟地址 . task_struct 中包含一个指向 mm_struct 结构的指针 . 进程的 mm_struct 中则包含了进程可执行影像的页目录指针 pgd. 还包含了指向 vm_area_struct 的几个指针 , 每个 vm_area_struct 包含一个进程的虚拟地址区域 .

一个进程有多个 vm_area_stuct 结构 .linux 要经常对进程分配 .. 或调整 vm_area_struct . 这样对 vm_area_stuct 的查找效率 . 对系统很有影像 . 所以在这里将所有的 vm_area_struct 形成了一个查找效率较高的平衡二叉树结构 .

我个人认为 , 在整个 linux 内核中这个地方 . 数据结构是最复杂的 . 如果把这一部分肯下来以后 , 整个内核便开始清晰了

 

分享到:
评论

相关推荐

    Java的内存管理机制分析

    ### Java的内存管理机制分析 #### 一、Java内存区域划分 Java的内存管理机制将内存分为以下几个区域: 1. **栈(Stack)**: - 存储局部变量(如基本类型的变量和对象的引用)。 - 每个线程拥有一个独立的栈。 ...

    SPARK内存管理机制最全!

    本文将详细介绍Spark内存管理机制,并探讨其优化的策略和实践。 首先,要了解Spark内存管理,先要区分Java堆内存和堆外内存。在Spark中,内存管理机制与JVM(Java虚拟机)有着紧密的联系。Java堆内存是JVM管理的...

    深度探索Windows CE的内存管理机制

    内存管理是操作系统的重要功能,深入地理解操作系统的内存管理机制是程序员写出高质量代码的必要条件之一。会带领大家领略Windows CE操作系统的内存管理机制,从硬件MMU的功能讲起,然后介绍虚拟地址空间布局,虚拟...

    python内存管理机制

    ### Python内存管理机制详解 #### 一、引言 Python作为一种高级动态语言,在运行时创建和销毁大量对象的过程中,内存管理扮演着至关重要的角色。它不仅直接影响到程序的执行效率,还关系到资源的合理利用。本文将...

    C#内存管理机制C#内存管理机制

    C#内存管理机制 C#内存管理机制是C#编程语言中的一种机制,旨在帮助程序员更好地管理内存资源。在C#中,程序员不需要手动管理内存,因为垃圾收集器会处理所有的内存清理工作。但是,了解C#内存管理机制仍然非常重要...

    sql内存管理机制

    【SQL内存管理机制】 SQL SERVER 2000的内存管理是其性能优化的关键部分,对于开发者来说,理解这一机制能帮助他们更好地优化数据库的运行效率。本文将深入探讨SQL SERVER 2000的内存管理,特别是从开发者的视角...

    一种Linux内存管理机制.pdf

    Linux内存管理机制包括多种层次和策略,旨在高效地分配和回收内存,避免内存耗尽和系统崩溃。本文将深入探讨Linux内存管理模型、伙伴系统、Slab分配流程以及内存回收策略。 首先,Linux内存管理模型将物理内存划分...

    安卓系统内存管理机制

    安卓系统的内存管理机制是理解Android性能和优化的关键因素。在这个机制中,主要涉及到两种类型的存储:RAM(随机访问内存)和ROM(只读存储器)。 RAM是Android系统中的临时数据存储区域,它用于存放运行中的应用...

    Linux内存管理机制的分析与研究

    ### Linux内存管理机制的分析与研究 #### 一、引言与重要性 内存管理作为操作系统的核心组件之一,其重要性和复杂性不言而喻。Linux操作系统,以其强大的灵活性和可定制性,提供了丰富的内存管理机制,使得即使是...

    Java内存管理机制相关资料汇总

    资源名称:Java内存管理机制相关资料汇总资源目录:【】java内存回收机制及预防【】java内存管理机制【】java内存管理白皮书【】Java虚拟机内存管理_对象和引用_空指针【】深入理解java虚拟机jvm高级行与最佳实践...

    MTK内存管理机制

    MTK内存管理机制是MediaTek(联发科)在设计其处理器平台时采用的一种内存管理系统,旨在高效地分配、管理和优化内存资源。MediaTek是一家知名的半导体公司,其芯片广泛应用于智能手机、电视、无线通信设备等多个...

    Windows内存管理机制.doc

    ### Windows内存管理机制详解 #### 一、进程地址空间 在Windows操作系统中,每个进程都有一个独立的虚拟地址空间,通常大小为4GB。这个地址空间被分为几个区域,包括代码段、数据段、堆栈段以及未初始化的数据段。...

    python内存管理机制原理详解

    Python的内存管理机制是其高效运行的关键之一,它包括了引用计数、垃圾回收和内存池等几个核心概念。下面将详细阐述这些机制的工作原理。 1. 引用计数: 引用计数是最基础的内存管理策略,它简单地记录每个对象被...

    Android内存管理机制研究_宋平波1

    Android内存管理机制研究 Android内存管理机制是Android操作系统的核心组件之一,负责管理和分配移动设备的内存资源。Android内存管理机制研究是移动应用开发者和研究人员需要深入了解和掌握的知识领域。本文将深入...

    Swift 语言的内存管理机制解析

    这是一种编译器自动实现的内存管理机制,它通过跟踪对象的引用计数来自动管理内存。当一个对象的引用计数降至零时,ARC 会自动释放该对象占用的内存,从而避免内存泄漏和过度分配。 Swift 的内存管理机制通过 ARC 为...

    全面介绍Windows内存管理机制

    根本的原因是,没有清楚的理解操作系统的内存管理机制,本文企图通过简单的总结描述,结合实例来阐明这个机制。 本文目的: 对Windows内存管理机制了解清楚,有效的利用C++内存函数管理和使用内存。 本文内容: 本文...

    C/C++内存管理机制

    本篇文章将深入探讨C/C++的内存管理机制,特别是内存池的概念,以及如何使用APR内存池和BOOST内存池。 首先,C/C++的内存分为四个主要区域:栈区、堆区、全局/静态存储区和常量存储区。栈区存储函数参数和局部变量...

    扩展的内存管理机制设计实验报告1

    【扩展的内存管理机制设计实验】的目的是深入理解实时嵌入式操作系统的内存管理机制,特别是针对内存碎片的处理和防止内存泄漏。实验基于Tornado和VxSim仿真环境,涉及的操作系统是实时多任务系统VxWorks。VxWorks在...

    内存管理机制的高效实现研究1

    本文主要探讨了在Windows环境下如何通过优化内存管理机制来提高效率,防止内存泄漏和越界访问。 首先,传统的动态内存管理机制在Windows 32位环境中主要依赖于默认堆。这个缺省堆是Win32子系统和C/C++运行时库进行...

Global site tag (gtag.js) - Google Analytics