![](https://img-blog.csdnimg.cn/20201014180756754.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
linux内存管理
文章平均质量分 76
bullbat
爱好程序设计,对待问题喜欢追根溯源。
展开
-
linux启动内存分配器
linux启动内存分配器是在伙伴系统、slab机制实现之前,为满足内核中内存的分配而建立的。本身的机制比较简单,使用位图来进行标志分配和释放。一、数据结构介绍1,保留区间因为在建立启动内存分配器的时候,会涉及保留内存。也就是说,之前保留给页表、分配器本身(用于映射的位图)、io等得内存在分配器建立后,当用它来分配内存空间时,保留出来的那些部分就不能再分配了。linux中对保留内存空间的原创 2012-01-04 20:23:29 · 3076 阅读 · 0 评论 -
Linux内存管理之slab机制(概述)
通过前面所有代码的分析和总结,已经把各个部分熟悉了一遍,在此对Linux内核中slab机制做最后的总结。伙伴系统算法采用页作为基本内存区,这适合于大块内存的请求。对于小内存区的申请,比如说几十或几百个字节,我们用slab机制。Slab分配器把对象分组放进高速缓存。每个高速缓存都是同类型对象的一种“储备”。包含高速缓存的主内存区被划分为多个slab,每个slab由一个活多个连续的页组成,这些原创 2012-01-11 21:01:49 · 31027 阅读 · 0 评论 -
linux内存管理概述
linux内存管理建立在基本的分页机制基础上,在linux内核中RAM的某些部分将会永久的分配给内核,并用来存放内核代码以及静态内核数据结构。RAM的其余部分称为动态内存,这不仅是进程所需的宝贵资源,也是内核本身所需的宝贵资源。实际上,整个系统的性能取决于如何有效地管理动态内存。因此,现在所有多任务操作系统都在经历优化对动态内存的使用,也就是说,尽可能做到当要时分配,不需要时释放。内存管理是o原创 2011-12-30 20:58:07 · 4314 阅读 · 2 评论 -
linux物理内存描述
linux使用于广泛的体系结构,因此需要用一种与体系结构无关的方式来描述内存。linux用VM描述和管理内存。在VM中兽药的普遍概念就是非一致内存访问。对于大型机器而言,内存会分成许多簇,依据簇与处理器“距离”的不同,访问不同的簇会有不同的代价。每个簇都被认为是一个节点(pg_data_t),每个节点被分成很多的成为管理区(zone)的块,用于表示内存中的某个范围。除了ZONE_DMA,ZON原创 2011-12-31 10:36:00 · 5645 阅读 · 2 评论 -
linux物理内存探测
linux在被bootloader加载到内存后, cpu最初执行的linux内核代码是/header.S文件中的start_of_setup函数,这个函数在做了一些准备工作后会跳转到boot目下文件main.c的main函数执行,在这个main函数中我们可以第一次看到与内存管理相关的代码,这段代码调用detect_memeory()函数检测系统物理内存在header.S中执行下面汇编代码:原创 2011-12-31 15:38:14 · 4284 阅读 · 0 评论 -
linux物理内存管理区初始化
Linux物理内存管理区在start_kernel函数中进行初始化,此时启动分配器已经建立,所以可以从bootmem中分配需要的内存。一、全局变量初始化max_pfn:最大物理页面帧号start_kernel()->setup_arch()->e820_end_of_ram_pfn()找出最大可用内存页面帧号。void __init setup_arch(char **cmdlin原创 2012-01-01 20:50:57 · 6154 阅读 · 1 评论 -
linux内存管理之活动内存区
Linux内存活动区域其实就是全局变量e820中的内存块做了相关的检查和对其处理后的区域。在管理区初始化等地方有用到。数据结构struct node_active_region { unsigned long start_pfn; unsigned long end_pfn; int nid;};初始化活动内存的初始化工作在setup_arch()->initmem原创 2012-01-01 21:01:16 · 3484 阅读 · 3 评论 -
linux页表机制管理初始化
linux页表机制的建立分为两个阶段,第一个阶段在启动初始化时,调用汇编代码实现临时的分页;第二阶段在内核初始化时建立完整的完整的页表机制。对于物理地址扩展(PAE)分页机制中,intel通过在她得处理器上把管脚数从32增加到36已经满足了这些需求,寻址能力可以达到64GB。不过,只有引入一种新的分页机制把32位线性地址转换为36位物理地址才能使用所增加的物理地址。linux为对多种体系的支持,选原创 2012-01-04 15:25:05 · 6225 阅读 · 1 评论 -
linux高端内存管理之永久内核映射
与直接映射的物理内存末端、高端内存的始端所对应的线性地址存放在high_memory变量中,在x86体系结构上,高于896MB的所有物理内存的范围大都是高端内存,它并不会永久地或自动地映射到内核地址空间,尽管x86处理器能够寻址物理RAM的范围达到4GB(启用PAE可以寻址到64GB)。一旦这些页被分配,就必须in射到内核的逻辑地址空间上。在x86上,高端内存中的页被映射到3GB-4GB。内核原创 2012-01-05 14:59:45 · 4324 阅读 · 0 评论 -
linux高端内存管理之临时内核映射
临时内核映射区属于高端内存中的固定内核映射区中的一部分。当必须创建一个映射而当前的上下文又不能睡眠时,内核提供了临时映射(也就是所谓的原子映射)。有一组保留的映射,他们可以存放新创建的临时映射。内核可以原子地把高端内存中的一个页映射到某个保留的映射中。因此,临时映射可以用在不能睡眠的地方,比如中断处理程序中,因为获取映射时绝不会阻塞。每个CPU都有他自己的窗口集合,他们用enum km_t原创 2012-01-05 15:14:44 · 3539 阅读 · 0 评论 -
linux内核高端内存管理之固定内存区与映射
前面总结了高端内存中永久内核映射和临时内核映射。linux高端内存中的临时内存区为固定内存区的一部分,下面是Linux内存布局图对于固定内存在linux内核中有下面描述enum fixed_addresses {#ifdef CONFIG_X86_32 FIX_HOLE, FIX_VDSO,#else VSYSCALL_LAST_PAGE, VSYSCALL_FIR原创 2012-01-05 19:31:38 · 4352 阅读 · 0 评论 -
Linux内存管理之slab机制(初始化)
一、内核启动早期初始化start_kernel()->mm_init()->kmem_cache_init()执行流程:1,初始化静态initkmem_list3三链;2,初始化cache_cache的nodelists字段为1中的三链;3,根据内存情况初始化每个slab占用的页面数变量slab_break_gfp_order;4,将cache_cache加入cache_c原创 2012-01-09 20:57:57 · 4804 阅读 · 1 评论 -
Linux内存管理之slab机制(分配对象)
Linux内核从slab中分配内存空间上层函数由kmalloc()或kmem_cache_alloc()函数实现。kmalloc()->__kmalloc()->__do_kmalloc()/** * __do_kmalloc - allocate memory * @size: how many bytes of memory are required. * @flags: the原创 2012-01-10 15:23:23 · 3709 阅读 · 1 评论 -
linux高端内存管理之非连续内存区(分配和释放)
前面总结了非连续内存区域的内核描述,接着看看他的分配和释放。一、非连续内存区的分配不管是vmalloc()还是vmalloc_32()等系列的分配函数最后都会调用__vmalloc_node()函数实现,直接看这个函数的实现。 * __vmalloc_node - allocate virtually contiguous memory * @size: allocation原创 2012-01-06 15:16:06 · 4237 阅读 · 0 评论 -
linux高端内存管理之非连续内存区(描述)
总结了高端内存区的固定内核映射区、临时内核映射与永久内核映射。但是对于高端内存中各个区间的布置我们任然不是很清楚,首先我们从整体上看看内核对高端内存的划分情况。如果内存足够大(比如用户:内核线性空间=3:1,内核就只能访问线性空间的第4GB内容,如果物理内存超过1GB则视为足够大),内核线性空间无法同时映射所有内存。这就需要将内核线性空间分出一段不直接映射物理内存,而是作为窗口分时映射使用原创 2012-01-06 14:43:26 · 4352 阅读 · 0 评论 -
linux内存管理之伙伴系统(建立)
内核使用伙伴系统来解决内存分配引起的外部碎片问题。一、数据结构描述结构zone中的free_area数组描述伙伴系统该数组为free_area结构struct zone {…… struct free_area free_area[MAX_ORDER];……};struct free_area {/*链表类型为5类,对于分类为新加入的*/ struct list_h原创 2012-01-07 22:01:53 · 3517 阅读 · 0 评论 -
linux内存管理之伙伴系统(内存分配)
一、Linux伙伴系统分配器伙伴系统分配器大体上分为两类。__get_free_pages()类函数返回分配的第一个页面的线性地址;alloc_pages()类函数返回页面描述符地址。不管以哪种函数进行分配,最终会调用alloc_pages()进行分配页面。为清楚了解其分配制度,先给个伙伴系统数据的存储框图也就是每个order对应一个free_area结构,free_area以不同原创 2012-01-08 21:11:37 · 10641 阅读 · 0 评论 -
Linux内存管理之伙伴系统(内存释放)
Linux内核伙伴系统中页面释放,主函数为free_pages()一、上层操作/*用虚拟地址进行释放*/void free_pages(unsigned long addr, unsigned int order){ if (addr != 0) { VM_BUG_ON(!virt_addr_valid((void *)addr)); __free_pages(virt_to原创 2012-01-09 10:06:49 · 4030 阅读 · 0 评论 -
Linux内存管理之slab机制(创建slab)
Linux内核中创建slab主要由函数cache_grow()实现,从slab的创建中我们可以完整地看到slab与对象、页面的组织方式。/* * Grow (by 1) the number of slabs within a cache. This is called by * kmem_cache_alloc() when there are no active objs left原创 2012-01-10 10:45:44 · 3663 阅读 · 0 评论 -
Linux内存管理之slab机制(销毁slab)
总结完了slab创建、对象分配、对象释放,在这里再看看slab的销毁。销毁slab很简单,由函数slab_destroy()实现。/** * slab_destroy - destroy and release all objects in a slab * @cachep: cache pointer being destroyed * @slabp: slab pointer bei原创 2012-01-10 20:55:07 · 3072 阅读 · 0 评论 -
Linux内存管理之slab机制(释放对象)
Linux内核中将对象释放到slab中上层所用函数为kfree()或kmem_cache_free()。两个函数都会调用__cache_free()函数。代码执行流程:1,当本地CPU cache中空闲对象数小于规定上限时,只需将对象放入本地CPU cache中;2,当local cache中对象过多(大于等于规定上限),需要释放一批对象到slab三链中。由函数cache_flusha原创 2012-01-10 17:23:15 · 4275 阅读 · 1 评论 -
Linux内存管理之slab机制(创建cache)
Linux内核中创建cache节点由函数kmem_cache_create()实现。该函数的执行流程:1,从全局cache_cache中获得cache结构,因为全局cache_cache初始化对象的大小就是kmem_cache结构的大小,所以返回的指针正好可以转换为cache结构;调用 kmem_cache_zalloc(&cache_cache, gfp);2,获得slab中碎片大小原创 2012-01-11 10:27:49 · 6322 阅读 · 0 评论 -
Linux内存管理之slab机制(销毁cache)
cache的销毁很简单,依次检查和释放本地CPU cache、共享cache、三链以及cache本身。从cache的创建我们看到,创建的cache主要是从cache_cache中获得的,因为cache_cache中对象的大小就是cache结构体的大小,所以这里只是释放到cache_cache就OK了。static void __kmem_cache_destroy(struct kmem_ca原创 2012-01-11 10:41:08 · 3461 阅读 · 0 评论 -
Linux内存管理之页面回收
请求调页机制,只要用户态进程继续执行,他们就能获得页框,然而,请求调页没有办法强制进程释放不再使用的页框。因此,迟早所有空闲内存将被分配给进程和高速缓存,Linux内核的页面回收算法(PFRA)采取从用户进程和内核高速缓存“窃取”页框的办法不从伙伴系统的空闲块列表。 实际上,在用完所有空闲内存之前,就必须执行页框回收算法。否则,内核很可能陷入一种内存请求的僵局中,并导致系统崩溃。也原创 2012-03-02 09:12:04 · 13598 阅读 · 3 评论