首先,让我们看下虚拟内存:
第一层理解
1. 每个进程都有自己独立的4G内存空间,各个进程的内存空间具有类似的结构
2. 一 个新进程建立的时候,将会建立起自己的内存空间,此进程的数据,代码等从磁盘拷贝到自己的进程空间,哪些数据在哪里,都由进程控制表中的 task_struct记录,task_struct中记录中一条链表,记录中内存空间的分配情况,哪些地址有数据,哪些地址无数据,哪些可读,哪些可 写,都可以通过这个链表记录
3. 每个进程已经分配的内存空间,都与对应的磁盘空间映射
Linux 使用虚拟地址空间,大大增加了进程的寻址空间,由低地址到高地址分别为:
只读段:该部分空间只能读,不可写;(包括:代码段、rodata 段(C常量字符串和#define定义的常量) )
数据段:保存全局变量、静态变量的空间;
堆 :就是平时所说的动态内存, malloc/new 大部分都来源于此。其中堆顶的位置可通过函数 brk 和 sbrk 进行动态调整。
文件映射区域 :如动态库、共享内存等映射物理空间的内存,一般是 mmap 函数所分配的虚拟地址空间。
栈:用于维护函数调用的上下文空间,一般为 8M ,可通过 ulimit –s 查看。
内核虚拟空间:用户代码不可见的内存区域,由内核管理(页表就存放在内核虚拟空间)
问题:
计算机明明没有那么多内存(n个进程的话就需要n*4G)内存
建立一个进程,就要把磁盘上的程序文件拷贝到进程对应的内存中去,对于一个程序对应的多个进程这种情况,浪费内存!
第二层理解
1. 每个进程的4G内存空间只是虚拟内存空间,每次访问内存空间的某个地址,都需要把地址翻译为实际物理内存地址
2. 所有进程共享同一物理内存,每个进程只把自己目前需要的虚拟内存空间映射并存储到物理内存上。
3. 进程要知道哪些内存地址上的数据在物理内存上,哪些不在,还有在物理内存上的哪里,需要用页表来记录
4. 页表的每一个表项分两部分,第一部分记录此页是否在物理内存上,第二部分记录物理内存页的地址(如果在的话)
5. 当进程访问某个虚拟地址,去看页表,如果发现对应的数据不在物理内存中,则缺页异常
6. 缺页异常的处理过程,就是把进程需要的数据从磁盘上拷贝到物理内存中,如果内存已经满了,没有空地方了,那就找一个页覆盖,当然如果被覆盖的页曾经被修改过,需要将此页写回磁盘
总结:
优点:
1.既然每个进程的内存空间都是一致而且固定的,所以链接器在链接可执行文件时,可以设定内存地址,而不用去管这些数据最终实际的内存地址,这是有独立内存空间的好处
2.当不同的进程使用同样的代码时,比如库文件中的代码,物理内存中可以只存储一份这样的代码,不同的进程只需要把自己的虚拟内存映射过去就可以了,节省内存
3.在程序需要分配连续的内存空间的时候,只需要在虚拟内存空间分配连续空间,而不需要实际物理内存的连续空间,可以利用碎片。
另 外,事实上,在每个进程创建加载时,内核只是为进程“创建”了虚拟内存的布局,具体就是初始化进程控制表中内存相关的链表,实际上并不立即就把虚拟内存对 应位置的程序数据和代码(比如.text .data段)拷贝到物理内存中,只是建立好虚拟内存和磁盘文件之间的映射就好(叫做存储器映射),等到运行到对应的程序时,才会通过缺页异常,来拷贝数 据。还有进程运行过程中,要动态分配内存,比如malloc时,也只是分配了虚拟内存,即为这块虚拟内存对应的页表项做相应设置,当进程真正访问到此数据 时,才引发缺页异常。
补充理解:
虚拟存储器涉及三个概念: 虚拟存储空间,磁盘空间,内存空间
可 以认为虚拟空间都被映射到了磁盘空间中,(事实上也是按需要映射到磁盘空间上,通过mmap),并且由页表记录映射位置,当访问到某个地址的时候,通过页 表中的有效位,可以得知此数据是否在内存中,如果不是,则通过缺页异常,将磁盘对应的数据拷贝到内存中,如果没有空闲内存,则选择牺牲页面,替换其他页 面。
mmap 是用来建立从虚拟空间到磁盘空间的映射的,可以将一个虚拟空间地址映射到一个磁盘文件上,当不设置这个地址时,则由系统自动设置,函数返回对应的内存地址 (虚拟地址),当访问这个地址的时候,就需要把磁盘上的内容拷贝到内存了,然后就可以读或者写,最后通过manmap可以将内存上的数据换回到磁盘,也就 是解除虚拟空间和内存空间的映射,这也是一种读写磁盘文件的方法,也是一种进程共享数据的方法 共享内存
在 内核态申请内存比在用户态申请内存要更为直接,它没有采用用户态那种延迟分配内存技术。内核认为一旦有内核函数申请内存,那么就必须立刻满足该申请内存的 请求,并且这个请求一定是正确合理的。相反,对于用户态申请内存的请求,内核总是尽量延后分配物理内存,用户进程总是先获得一个虚拟内存区的使用权,最终 通过缺页异常获得一块真正的物理内存。
1.物理内存的内核映射
IA32架构中内核虚拟地址空间只有1GB大小(从3GB到4GB),因此可以直接将1GB大小的物理内存(即常规内存)映射到内核地址空间,但超出1GB大小的物理内存(即高端内存)就不能映射到内核空间。为此,内核采取了下面的方法使得内核可以使用所有的物理内存。
1).高端内存不能全部映射到内核空间,也就是说这些物理内存没有对应的线性地址。不过,内核为每个物理页框都分配了对应的页框描述符,所有的页框描述符 都保存在mem_map数组中,因此每个页框描述符的线性地址都是固定存在的。内核此时可以使用alloc_pages()和alloc_page()来 分配高端内存,因为这些函数返回页框描述符的线性地址。
2).内核地址空间的后128MB专门用于映射高端内存,否则,没有线性地址的高端内存不能被内核所访问。这些高端内存的内核映射显然是暂时映射的,否则 也只能映射128MB的高端内存。当内核需要访问高端内存时就临时在这个区域进行地址映射,使用完毕之后再用来进行其他高端内存的映射。
由于要进行高端内存的内核映射,因此直接能够映射的物理内存大小只有896MB,该值保存在high_memory中。内核地址空间的线性地址区间如下图所示:
从图中可以看出,内核采用了三种机制将高端内存映射到内核空间:永久内核映射,固定映射和vmalloc机制。
2.物理内存管理机制
基 于物理内存在内核空间中的映射原理,物理内存的管理方式也有所不同。内核中物理内存的管理机制主要有伙伴算法,slab高速缓存和vmalloc机制。其 中伙伴算法和slab高速缓存都在物理内存映射区分配物理内存,而vmalloc机制则在高端内存映射区分配物理内存。
伙伴算法
伙伴算法负责大块连续物理内存的分配和释放,以页框为基本单位。该机制可以避免外部碎片。
per-CPU页框高速缓存
内核经常请求和释放单个页框,该缓存包含预先分配的页框,用于满足本地CPU发出的单一页框请求。
slab缓存
slab缓存负责小块物理内存的分配,并且它也作为高速缓存,主要针对内核中经常分配并释放的对象。
vmalloc机制
vmalloc机制使得内核通过连续的线性地址来访问非连续的物理页框,这样可以最大限度的使用高端物理内存。
3.物理内存的分配
内核发出内存申请的请求时,根据内核函数调用接口将启用不同的内存分配器。
3.1 分区页框分配器
分区页框分配器 (zoned page frame allocator) ,处理对连续页框的内存分配请求。分区页框管理器分为两大部分:前端的管理区分配器和伙伴系统,如下图:
管理区分配器负责搜索一个能满足请求页框块大小的管理区。在每个管理区中,具体的页框分配工作由伙伴系统负责。为了达到更好的系统性能,单个页框的申请工作直接通过per-CPU页框高速缓存完成。
该分配器通过几个函数和宏来请求页框,它们之间的封装关系如下图所示。
这些函数和宏将核心的分配函数__alloc_pages_nodemask()封装,形成满足不同分配需求的分配函数。其中,alloc_pages()系列函数返回物理内存首页框描述符,__get_free_pages()系列函数返回内存的线性地址。
3.2 slab分配器
slab 分配器最初是为了解决物理内存的内部碎片而提出的,它将内核中常用的数据结构看做对象。slab分配器为每一种对象建立高速缓存。内核对该对象的分配和释放均是在这块高速缓存中操作。一种对象的slab分配器结构图如下:
可以看到每种对象的高速缓存是由若干个slab组成,每个slab是由若干个页框组成的。虽然slab分配器可以分配比单个页框更小的内存块,但它所需的所有内存都是通过伙伴算法分配的。
slab高速缓存分专用缓存和通用缓存。专用缓存是对特定的对象,比如为内存描述符创建高速缓存。通用缓存则是针对一般情况,适合分配任意大小的物理内存,其接口即为kmalloc()。
3.3 非连续内存区内存的分配
内 核通过vmalloc()来申请非连续的物理内存,若申请成功,该函数返回连续内存区的起始地址,否则,返回NULL。vmalloc()和 kmalloc()申请的内存有所不同,kmalloc()所申请内存的线性地址与物理地址都是连续的,而vmalloc()所申请的内存线性地址连续而 物理地址则是离散的,两个地址之间通过内核页表进行映射。
vmalloc()的工作方式理解起来很简单:
1).寻找一个新的连续线性地址空间;
2).依次分配一组非连续的页框;
3).为线性地址空间和非连续页框建立映射关系,即修改内核页表;
vmalloc() 的内存分配原理与用户态的内存分配相似,都是通过连续的虚拟内存来访问离散的物理内存,并且虚拟地址和物理地址之间是通过页表进行连接的,通过这种方式可 以有效的使用物理内存。但是应该注意的是,vmalloc()申请物理内存时是立即分配的,因为内核认为这种内存分配请求是正当而且紧急的;相反,用户态 有内存请求时,内核总是尽可能的延后,毕竟用户态跟内核态不在一个特权级。
http://my.oschina.net/zhengyijie/blog/551401
相关推荐
Linux虚拟内存管理是操作系统设计中的核心部分,它允许程序访问比实际物理内存更大的地址空间,同时优化了内存的使用效率。这一系统通过映射技术,将进程的虚拟地址转换为实际物理地址,使得多个进程可以共享同一...
Linux虚拟内存管理是操作系统核心的重要组成部分,它负责为应用程序提供比物理内存更大的地址空间,并有效地管理物理内存资源。本资料“深入理解Linux虚拟内存管理”旨在帮助读者深入了解这一复杂的系统机制,包括...
Linux虚拟内存的实现需要6种机制的支持:地址映射机制、内存分配回收机制、缓存和刷新机制、请求页机制、交换机制和内存共享机制。 在Linux中,虚拟内存管理是通过地址映射机制把用户程序的逻辑地址映射到物理地址...
通过深入研究《深入理解Linux虚拟内存管理》,我们可以了解到Linux如何高效地管理虚拟内存,以支持多个进程同时运行并确保系统的稳定性和性能。虚拟内存管理不仅是Linux操作系统的重要组成部分,也是现代计算机科学...
Linux虚拟内存管理是操作系统核心的重要组成部分,它负责为运行中的进程分配和管理内存资源。在Linux系统中,每个进程都有自己独立的虚拟地址空间,这个空间是逻辑上的,并非实际物理内存的直接映射。虚拟内存管理...
详细描述Linux虚拟内存,提供理论基础和逐行源代码注释。 它系统地涵盖了从物理内存描述到内存不足管理的所有内容。
Linux 内核的内存管理探秘之四 虚拟内存的管理 Linux 操作系统中,内存管理是非常重要的...虚拟内存技术是 Linux 内核中一个非常重要的机制,它使得系统能够运行比物理内存大的程序,同时也提高了系统的可用性和性能。
本文将详细介绍Linux虚拟内存管理机制,包括物理内存的描述、页表管理、进程地址空间、启动时内存分配器、物理页面分配、非连续内存分配、slab分配器以及高内存管理等核心概念和技术细节。 #### 物理内存描述 物理...
在Linux系统中,这一功能同样存在,对于那些希望优化系统性能或者解决内存不足问题的用户来说,了解如何设置和管理虚拟内存至关重要。 #### 步骤一:查看当前内存状态 首先,我们需要检查当前的内存使用情况。在...
在Linux操作系统中,内存管理是一项核心任务,尤其是其虚拟内存机制,这使得每个进程拥有独立且隔离的4GB线性虚拟地址空间。这种设计的主要优点是保护操作系统免受用户程序的直接干扰,同时允许程序使用超过实际物理...
《深入理解Linux虚拟内存》是一本专为对Linux操作系统感兴趣的读者设计的专业书籍,它深入探讨了Linux内核如何管理和利用虚拟内存这一核心功能。虚拟内存是现代操作系统中的关键组件,它使得程序可以运行在比物理...
本文将详细阐述Linux操作系统的内存管理机制,包括物理内存和虚拟内存的管理机制、地址映射机制、内存碎片和内存不连续的问题解决等。 Linux操作系统的内存管理机制旨在解决进程需要使用的代码和数据都放在内存中,...
Linux虚拟内存是一个操作系统级别的技术,它为每个进程提供了一个独立且连续的内存空间,即使物理内存实际是分散的。在Linux系统中,虚拟内存的概念至关重要,因为它允许系统同时运行多个进程,而不需要每个进程都...
Linux虚拟内存管理是操作系统核心的重要组成部分,它负责管理和优化系统中的内存资源,使得应用程序能够高效地使用物理内存和硬盘上的交换空间。在Linux系统中,虚拟内存并不是一个实际的硬件特性,而是一种软件策略...
在现代操作系统中,虚拟内存是一项至关重要的技术,它允许系统以比实际物理内存更大的地址空间运行。Linux系统通过虚拟内存管理机制,有效地...希望本文的详细介绍能帮助你更好地理解和优化Linux系统的虚拟内存管理。
Linux虚拟内存管理是操作系统核心的重要组成部分,它负责为应用程序分配和管理内存资源,确保系统能够高效、稳定地运行。在Linux系统中,虚拟内存的概念使得每个进程都有自己独立的内存空间,这种隔离使得进程之间...
Linux虚拟内存管理机制是操作系统中非常重要的一部分,它不仅能够有效利用有限的物理内存资源,还能通过各种高级算法和技术提高系统的整体性能。通过对虚拟内存的理解,开发者和系统管理员可以更好地优化应用程序和...
在本实验中,我们主要探讨了Linux虚拟内存管理的原理、动态内存操作函数的使用,以及如何检测主存使用情况。 首先,Linux内存管理采用虚拟内存技术,将每个进程的地址空间划分为多个区域,如堆、栈、代码段、数据段...
Linux虚拟内存管理机制 Linux操作系统的虚拟内存管理机制是指Linux操作系统中用于管理内存的机制,该机制使得操作系统可以更好地管理和分配内存资源,从而提高系统的性能和稳定性。虚拟内存管理机制是 Linux操作...