内存管理-SLAB(创建SLAB高速缓存kmem_cache_create())

kmem_cache的创建和释放-slub分配器 目录 kmem_cache_create kmem_cache_create_usercopy __kmem_cache_alias find_mergeable create_cache __kmem_cache_create kmem_cache_open kmem_cache_destroy shutdown_cache 内核版本:kernel-4.19 ​​​​​​​kmem_cache是slub... 阅读详情

这篇主要讲解专用高速缓存的创建函数kmem_cache_create()的流程。kmem_cache_create()主要是建立的cache描述符,填充了其成员,设置cpu local slab,设置外置slab描述符还是内置slab描述符,并没有分配slab块和对象。最终将cache描述符添加到cache_chain链表上。

首先写了一个简单的测试程序:

[cpp]  view plain copy
  1. #include <linux/module.h>  
  2. #include <linux/init.h>  
  3. #include <linux/kernel.h>   
  4. #include <linux/mm.h>  
  5. #include <linux/errno.h>  
  6. #include <linux/slab.h>  
  7. #include <linux/gfp.h>  
  8.   
  9. struct slab_test{  
  10.     int val;  
  11. };  
  12.   
  13. static int n;  
  14. struct kmem_cache *test_cachep = NULL;  
  15. struct slab_test *object1 = NULL, *object2 = NULL;  
  16.   
  17. void slab_ctor(void *cachep){  
  18.     printk("slab_ctor is called! object %d has been inited!\n", n);  
  19.     n++;  
  20. }  
  21.   
  22.   
  23. static int __init slab_test_init(void){  
  24.     printk("slab test module init\n");  
  25.     n = 0;  
  26.     test_cachep = kmem_cache_create("slab_test_cachep", sizeof(struct slab_test), 0, SLAB_HWCACHE_ALIGN, slab_ctor);  
  27.     if(!test_cachep)  
  28.         return -ENOMEM;  
  29.     object1 = kmem_cache_alloc(test_cachep, GFP_KERNEL);  
  30.     if(!object1)  
  31.         return -ENOMEM;  
  32.     else  
  33.         printk("object one has been created!\n");  
  34.     object2 = kmem_cache_alloc(test_cachep, GFP_KERNEL);  
  35.     if(!object2)  
  36.         return -ENOMEM;  
  37.     else  
  38.         printk("object two has been created!\n");  
  39.     return 0;  
  40. }  
  41.   
  42. static void __exit slab_test_exit(void){  
  43.     printk("slab test module exit\n");  
  44.     kmem_cache_free(test_cachep, object1);  
  45.     kmem_cache_free(test_cachep, object2);  
  46.     if(test_cachep)  
  47.         kmem_cache_destroy(test_cachep);  
  48. }  
  49.   
  50. module_init(slab_test_init);  
  51. module_exit(slab_test_exit);  
  52. MODULE_LICENSE("GPL");  
  53. MODULE_AUTHOR("embeddedlwp@163.com");  
  54. MODULE_DESCRIPTION("slab test module");  

dmesg一下看log:

[  103.617426] slab test module init
[  103.617427] slab_ctor is called! object 0 has been inited!
[  103.617429] slab_ctor is called! object 1 has been inited!
[  103.617430] slab_ctor is called! object 2 has been inited!
                          ............
                          ............
[  103.617761] slab_ctor is called! object 506 has been inited!
[  103.617762] slab_ctor is called! object 507 has been inited!
[  103.617763] object one has been created!
[  103.617766] object two has been created!
当我没有调用kmem_cache_alloc(),只调用kmem_cache_create()的时候是没有调用对象的构造函数的,可以对照源码,调用kmem_cache_create()并没有分配slab,是在创建对象的时候发现没有空闲对象,调用cache_grow()分配一个slab,然后再分配对象。所以这里调用构造函数初始化的object都是刚分配的slab中的。cat/proc/slabinfo看一下,发现最上边出现我们新创建的cache,slab_test_cachep,其中active_objs为2,num_objs为508,正好与我们的实际信息相符合。


kmem_cache_t  *kmem_cache_create (const char *name, size_t size, size_t align,
unsigned long flags, void (*ctor)(void*, kmem_cache_t *, unsigned long),
void (*dtor)(void*, kmem_cache_t *, unsigned long))
{
size_t left_over, slab_size, ralign;
kmem_cache_t *cachep = NULL;
        /*高速缓存的名字不能为空,不能在中断上下文(这个函数应该会导致睡眠),大小不能太大,也不能太小,如果有析构函数就必须有构造函数*/

if ((!name) ||
in_interrupt() ||
(size < BYTES_PER_WORD) ||
(size > (1<<MAX_OBJ_ORDER)*PAGE_SIZE) ||
(dtor && !ctor)) {
printk(KERN_ERR "%s: Early error in slab %s\n",
__FUNCTION__, name);
BUG();
}

/*缺省的情况下,创建的cache大小要字对齐的*/

if (size & (BYTES_PER_WORD-1)) {

size += (BYTES_PER_WORD-1);
size &= ~(BYTES_PER_WORD-1);
}

        /*

         *如果想让新创建的slab高速缓存所包含的对象在第一级硬件高速缓存中对齐,则设置SLAB_HWCACHE_ALIGN标志

         *这里的处理方式是,如果对象的大小大于cache line大小的一半,就在RAM中根据L1_CACHE_BYTES的倍数对齐对象。

         *否则,对象的大小就是L1_CACHE_BYTES的因子取整。这可以保证一个小对象不会横跨两个高速缓存行。

         *对齐的时候需要填充空白,即通过人为地增加对象的大小来获得较好的高速缓存性能,是一个以时间换空间的过程。

         */

        if (flags & SLAB_HWCACHE_ALIGN) {
ralign = cache_line_size();
while (size <= ralign/2)
ralign /= 2;
} else {
ralign = BYTES_PER_WORD;
}

align = ralign;

        /*在上一篇已经提到cache_cache包含其他高速缓存使用的高速缓存描述符,它也是一个cache,专门用来分配cache描述符的*/

/* Get cache's description obj. */
cachep = (kmem_cache_t *) kmem_cache_alloc(&cache_cache, SLAB_KERNEL);
if (!cachep)
goto opps;

        /*将这个cache清0*/

        memset(cachep, 0, sizeof(kmem_cache_t));

        /*如果对象的大小大于1/8的页大小,则使用外部slab描述符*/
/* Determine if the slab management is 'on' or 'off' slab. */
if (size >= (PAGE_SIZE>>3))
/*
 * Size is large, assume best to place the slab management obj
 * off-slab (should allow better packing of objs).
 */
flags |= CFLGS_OFF_SLAB;


size = ALIGN(size, align);
  
        /*在内碎片和cache所占页数之前取一个平衡值*/
if ((flags & SLAB_RECLAIM_ACCOUNT) && size <= PAGE_SIZE) {
/*
 * A VFS-reclaimable slab tends to have most allocations
 * as GFP_NOFS and we really don't want to have to be allocating
 * higher-order pages when we are unable to shrink dcache.
 */
cachep->gfporder = 0;
cache_estimate(cachep->gfporder, size, align, flags,
&left_over, &cachep->num);
} else {
/*
 * Calculate size (in pages) of slabs, and the num of objs per
 * slab.  This could be made much more intelligent.  For now,
 * try to avoid using high page-orders for slabs.  When the
 * gfp() funcs are more friendly towards high-order requests,
 * this should be changed.
 */
do {
unsigned int break_flag = 0;
cal_wastage:

                       /*计算内碎片的大小*/

                        cache_estimate(cachep->gfporder, size, align, flags,
&left_over, &cachep->num);
if (break_flag)
break;
if (cachep->gfporder >= MAX_GFP_ORDER)
break;
if (!cachep->num)
goto next;
if (flags & CFLGS_OFF_SLAB &&
cachep->num > offslab_limit) {
/* This num of objs will cause problems. */
cachep->gfporder--;
break_flag++;
goto cal_wastage;
}


/*
 * Large num of objs is good, but v. large slabs are
 * currently bad for the gfp()s.
 */
if (cachep->gfporder >= slab_break_gfp_order)
break;
                        /*平衡的值*/

if ((left_over*8) <= (PAGE_SIZE<<cachep->gfporder))
break; /* Acceptable internal fragmentation. */
next:
cachep->gfporder++;
} while (1);
}


if (!cachep->num) {
printk("kmem_cache_create: couldn't create cache %s.\n", name);
kmem_cache_free(&cache_cache, cachep);
cachep = NULL;
goto opps;
}
         /*按照align对齐*/
         slab_size = ALIGN(cachep->num*sizeof(kmem_bufctl_t)
+ sizeof(struct slab), align);


/*如果内碎片的大小比slab管理对象(即slab描述符的大小+所有对象描述符的大小)大,则改成内部slab描述符*/ 
if (flags & CFLGS_OFF_SLAB && left_over >= slab_size) {
flags &= ~CFLGS_OFF_SLAB;
left_over -= slab_size;
}


        /*如果是外置slab描述符,就不用对齐了*/
if (flags & CFLGS_OFF_SLAB) {
/* really off slab. No need for manual alignment */
slab_size = cachep->num*sizeof(kmem_bufctl_t)+sizeof(struct slab);
}
 
        /*着色粒度的单位为CPU一级硬件高速缓存中cache line的大小*/
cachep->colour_off = cache_line_size();
/* Offset must be a multiple of the alignment. */
if (cachep->colour_off < align)
cachep->colour_off = align;
        /*计算着色粒度的最大值*/
cachep->colour = left_over/cachep->colour_off;
        /*获得单个slab的大小*/
cachep->slab_size = slab_size;
cachep->flags = flags;
cachep->gfpflags = 0;
if (flags & SLAB_CACHE_DMA)
cachep->gfpflags |= GFP_DMA;
spin_lock_init(&cachep->spinlock);
cachep->objsize = size;
/* NUMA */
        /*初始化slabs_full,slabs_partial,slabs_free链表头*/
INIT_LIST_HEAD(&cachep->lists.slabs_full);
INIT_LIST_HEAD(&cachep->lists.slabs_partial);
INIT_LIST_HEAD(&cachep->lists.slabs_free);
      
        /*
         *如果是外置的slab描述符,则从malloc_sizes指向的26个高速还从中选择合适的,
         *这里并没有分配外置的slab管理对象,而是在调用cache_grow()分配新的slab块的时候才分配的
         */  
if (flags & CFLGS_OFF_SLAB)
cachep->slabp_cache = kmem_find_general_cachep(slab_size,0);
        /*设置cache的名字和构造,析构函数*/
cachep->ctor = ctor;
cachep->dtor = dtor;
cachep->name = name;

/* Don't let CPUs to come and go */
lock_cpu_hotplug();

/*设置CPU local slab*/
if (g_cpucache_up == FULL) {
enable_cpucache(cachep);
} else {
if (g_cpucache_up == NONE) {
/* Note: the first kmem_cache_create must create
* the cache that's used by kmalloc(24), otherwise
* the creation of further caches will BUG().
*/
cachep->array[smp_processor_id()] = &initarray_generic.cache;
g_cpucache_up = PARTIAL;
} else {
cachep->array[smp_processor_id()] = kmalloc(sizeof(struct arraycache_init),GFP_KERNEL);
}
BUG_ON(!ac_data(cachep));
ac_data(cachep)->avail = 0;
ac_data(cachep)->limit = BOOT_CPUCACHE_ENTRIES;
ac_data(cachep)->batchcount = 1;
ac_data(cachep)->touched = 0;
cachep->batchcount = 1;
cachep->limit = BOOT_CPUCACHE_ENTRIES;
cachep->free_limit = (1+num_online_cpus())*cachep->batchcount
+ cachep->num;
} 
cachep->lists.next_reap = jiffies + REAPTIMEOUT_LIST3 +
((unsigned long)cachep)%REAPTIMEOUT_LIST3;



        /*获得使链表免受被同时访问的cache_chain_sem信号量*/   
down(&cache_chain_sem);
{
struct list_head *p;
mm_segment_t old_fs;


old_fs = get_fs();
set_fs(KERNEL_DS);
list_for_each(p, &cache_chain) {
kmem_cache_t *pc = list_entry(p, kmem_cache_t, next);
char tmp;
/* This happens when the module gets unloaded and doesn't
   destroy its slab cache and noone else reuses the vmalloc
   area of the module. Print a warning. */
if (__get_user(tmp,pc->name)) { 
printk("SLAB: cache with size %d has lost its name\n", 
pc->objsize); 
continue; 
} 
if (!strcmp(pc->name,name)) { 
printk("kmem_cache_create: duplicate cache %s\n",name); 
up(&cache_chain_sem); 
unlock_cpu_hotplug();
BUG(); 
}
}
set_fs(old_fs);
}

       /*将新建立的cache插入cache_chain链表中*/

list_add(&cachep->next, &cache_chain);

       /*释放这个信号量*/

up(&cache_chain_sem);
unlock_cpu_hotplug();
opps:
if (!cachep && (flags & SLAB_PANIC))
panic("kmem_cache_create(): failed to create slab `%s'\n",
name);
return cachep;
}
EXPORT_SYMBOL(kmem_cache_create);


Linux内存管理—Slab分配器 Slab分配器的引入 内部碎片 内部碎片就是已经被分配出去(能明确指出属于哪个进程)却不能被利用的内存空间 内部碎片是处于区域内部或页面内部的存储块。占有这些区域或页面的进程并不使用这个存储块。而在进程占有这块存储块时,系统无法利用它。直到进程释放它,或进程结束时,系统才有可能利用这个存储块。 举例:某进程向系统申请了3K内存空间,系统通过伙伴系统算法可能分配给进程4K(一个标准页面)内存空间,导... 阅读详情

相关推荐

linux内核分析———SLAB原理及实现

<!-- @page {margin:0.79in} p {margin-bottom:0.08in; direction:ltr; color:#000000; text-align:justify; widows:0; orphans:0} p.western {font-family:"Times New Roman",serif; font-siz

chenxiancool的专栏 1万+

Linux内核源码剖析之kmem_cache_create

一个操作系统对于内存的管理是非常的重要,关乎到整个系统的运行效率和内存最大使用率。内存管理从宏观来看,无非就是使内存达到最大使用率,减少内存的内/外碎片。而在Linux内核中使用伙伴算法(Buddy)管理一组页,使用Slab算法管理单独页,伙伴算法+Slab算法合理的避免内存的内/外碎片。那么今天介绍的kmem_cache_create方法就是Slab算法。

李哈zzz的博客 2376

内存管理之slab分配器

STL中的空间配置器采用一、二级配置器进行内存管理,当配置区块    在一级配置器中,allocate()直接使用malloc(),deallocate()直接使用free(),对于内存不足的情况,模拟C++的set_new_handler()机制;      在二级配置器中,首先会维护16个自由链表(free lists),负责16种小型区块的次配置能力;如果内存不足,转调一级配置器中的set_...

hhhanpan的博客 979

内存管理API之kmem_cache_create

struct kmem_cache * kmem_cache_create(const char *name, size_t size, size_t align, slab_flags_t flags, void (*ctor)(void *)) 用于创建一个新的slab 缓存,一般在驱动初始化的时候用。 其使用的例程如下: amd_iommu_irq_cache = kmem_ca

jason的笔记 1835

Linux内核:内存管理——slab分配器

Linux内核中基于伙伴算法实现的分区页框分配器适合大块内存的请求,它所分配的内存区是以页框为基本单位的。对于内核中小块连续内存的请求,比如说几个字节或者几百个字节,如果依然分配一个页框来来满足该请求,那么这很明显就是一种浪费,即产生内部碎片(internal fragmentation)为了解决小块内存的分配,Linux内核基于Solaris 2.4中的slab分配算法实现了自己的slab分配器。除此之外,slab分配器另一个主要功能是作为一个高速缓存,它用来存储内核中那些经常分配并释放的对象。

m0_74282605的博客 968

Linux内存管理(33):slub 分配器之__kmem_cache_create

是数据结构 kmem_cache 创建的核心函数,无论是在slab 初始化期间,还是在用户层调用 kmem_cache_create() 创建slab 描述符时,都离不开这个核心函数。为了减少slab 初始化和 kmem_cache_create() 博文的繁琐,我们将该函数单独提出来剖析。本文重点分析slub 分配器中 __kmem_cache_create() 的实现过程。

私房菜 1644

kernel hacker修炼之道之内存管理-SLAB(创建SLAB高速缓存kmem_cache_create())

创建SLAB高速缓存kmem_cache_create() 作者:李万鹏 于北京 borqs 这篇主要讲解专用高速缓存的创建函数kmem_cache_create()的流程。kmem_cache_create()主要是建立的cache描述符,填充了其成员,设置cpu local slab,设...

tomhibolu 356

Linux内存管理(35):slub 分配器之kmem_cache_create

slub 分配器初始化》一文中我们详细分析了slub 分配的初始化流程,最开始slub 系统没创建好,系统利用了局部变量和,临时创建了两个slab,创建完成后使用将全局变量和管理结构迁入,摆脱静态局部变量管理,至此slub 系统初步形成。紧接着通过创建kmalloc 需要的 slab caches(大概14组),此时通过更新为UP,标记slub 系统正式创建完成。

私房菜 1127

Linux内存管理之SLAB分配器

注:本文讲述的SLAB相关代码是基于Linux内核v4.7,代码网址。 1、SLAB分配器的由来 在讲SLAB分配器之前先说两个概念: 内部碎片和外部碎片。 外部碎片指的是还没有被分配出去(不属于任何进程)但由于太小而无法分配给申请内存空间的新进程的内存空闲区域。外部碎片是除了任何已分配区域或页面外部的空闲存储块。这些存储块的总和可以满足当前申请的长度要求,但是由于它们的地址不连续或其他原因...

ibless的博客 9244

linux内存管理 -- Slab

碎片即一个完整的东西被打碎,零散的分布着。这就像内存,如果不加以管理,就会有很多未被使用的碎片,造成内存的浪费。 在linux中,内存是以页(page)来管理的,一page一般为4KB,而外部/内部碎片就是以page为界线划分的。内部碎片就是指被内核分配出去但是不能被利用的内存,而外部碎片是指由于频繁地申请和释放页框而导致的某些小的连续页框,比方只有一个页框,无法分配给需要大的连续页框的进程而导致的内存碎片。如一个page的前后都被分配了出去,没有其他page与之相连,这个page就成了外部碎片。这时候bu

badbayyj的博客 3296

Linux内核空间内存管理(三):slab内存分配机制剖析

slab概述、基本设计原则 、slab层的设计 、slab 描述符 、普通和专用高速缓存 、与slab分配器有关的全局变量 、创建缓存 、创建slab 与 cache_grow() 、slab的销毁:退还内存与kmem_cache_destroy() 、内存请求路径

ZY-JIMMY 2182

kmem_cache_alloc, kmem_cache_create, struct kmem_cache

来自:http://linux.chinaunix.net/bbs/viewthread.php?tid=913690   为了更好的得到问题解决,也对问题的提出进点义务,在抛出我的问题前先简单介绍一下Linux下slab高速缓存的使用方法。 在内核编程中,可能经常会有一些数据结构需要反复使用和释放,按照通常的思路,可能是使用kmalloc和kfree来实现。 但是这种方式效率不高,L

6191

安卓开发者必看:Win11最新Fastboot驱动安装避坑指南(含Android Bootloader Interface选择技巧)

本文为安卓开发者提供了Windows 11系统下Fastboot驱动安装的详细指南,特别针对Android Bootloader Interface选择技巧和多设备并发连接时的驱动冲突问题。通过解析Windows 11的特殊驱动验证机制,推荐使用Google官方USB驱动,并提供安装流程、版本选择建议及疑难问题排查方法,帮助开发者高效完成开发环境配置。

sea99的博客 1328

linux驱动开发(5)-kmem_cache

函数会根据per-CPU缓存状态来尽量做最优化处理(内核总是挖空心思去干这种事情,还常常乐此不疲)​,但是我们可以想象free一个在kmem_cache中的内存对象,必然会引起一连串的连锁反应:如果要释放的对象恰恰是该slab上唯一被分配的对象,那么由于它的释放,将导致整个slab空闲,这种情况下内核有可能将该slab所对应的页面释放给伙伴系统,同时把该slab从kmem_cache对象的slabs_partial链表中摘除,更新对应的管理数据。参数cachep是要销毁的kmem_cache对象的指针。

yyc的博客 872

飞书文档API深度使用指南:如何用n8n社区节点绕过HTTP Request的复杂配置

本文详细解析了如何利用n8n社区节点简化飞书文档API的集成过程,绕过复杂的HTTP Request配置。通过n8n-feishu-lite社区节点,开发者可以轻松实现飞书文档的创建、编辑和查询操作,大幅提升自动化工作流的效率。文章还提供了高级应用场景和性能优化建议,帮助开发者更好地利用飞书开放平台的API功能。

weixin_29227585的博客 83

无人驾驶汽车系统入门(三十二)——FEC算法:点云快速欧几里得聚类实战解析

本文深入解析了FEC算法在无人驾驶点云聚类中的高效应用,通过逐点处理策略和体素栅格预分割技术,实现了比传统欧几里得聚类快百倍的速度。文章详细介绍了算法原理、Python实现及参数调优指南,并对比了FEC与传统算法的性能差异,为无人驾驶系统开发提供了实用解决方案。

weixin_29065015的博客 484

内核函数 kmem_cache_xxxx

struct kmem_cache *kmem_cache_create (const char *name,                                                                                  size_t size,                                                   ...

yldfree的博客 3177

autoDL算力云装Xinference[坑与步骤]

在页面直接点击下载会出现下着下载进度条消失,试了几次才出现这个报错,现在我们就继续安装缺少的包吧。这一步成功绕开了系统盘空间限制。先租用一个合适的服务器,建议不要选最新版本,跟我选的一样即可,不然后面会出现。最近在 AutoDL 上尝试部署。🚫 不要直接使用以下命令。点击下面链接即可打开。

ngadminq的博客 2382

Linux内存管理之slab 2:slab API

Linux内存管理之slab 2:slab API1. kmem_cache_create1.1 kmem_cache_create (仅分配一个kmem_cache实例)未分配实际物理页1.2 slab 创建流程1.3 slab 与伙伴系统2. kmem_cache_alloc2.1 kmem_cache_create 和 kmem_cache_alloc 关系2.2 kmalloc 函数本质2.3 kfree 函数本质3. kmem_cache_zalloc (zero 清零)3.1 kmem_cach

哈尼的博客 1195

从理论到实践:全面解析Cmk(设备能力指数)的应用与优化

本文全面解析了设备能力指数Cmk的核心概念、计算逻辑与关键应用场景。Cmk作为衡量设备本身固有加工能力的黄金标准,在设备验收、大修后验证及过程能力根因分析中至关重要。文章通过实战案例,详细阐述了执行Cmk测试的“五大固定”黄金法则、数据计算分析方法,并提供了Cmk不达标时的系统性排查与优化策略,帮助制造企业实现预防性质量管理。

jump7的博客 518

Serial RapidIO Gen2 IP 说明(三)

前言 继续接着上篇文章,介绍Serial RapidIO Gen2 IP 的具体端口信息。 一、端口描述 1、缓冲设计接口 2、物理层接口 参考说明 【1】Serial RapidIO Gen2 v4.1https://china.xilinx.com/content/dam/xilinx/support/documentation/ip_documentation/srio_gen2/v4_1/pg007_srio_gen2.pdf ...

记录所学,分享知识,结识挚友 1319

slab机制的原理

slab获取 - 效率最高的获取方法 分配和释放数据结构是所有内核中最普遍的操作之一。为了便于数据的频繁分配和回收,常常会用到一个空间链表。它就相当于对象高速缓存以便快速存储频繁使用的对象类型。在内核中,空闲链表面临的主要问题之一是不能全局控制。当可用内存变得紧张的时候,内核无法通知每个空闲链表,让其收缩缓存的大小以便释放一些内存来。实际上,内核根本不知道有这样的空闲离岸边。为了弥补这一缺陷,也为了是代码更加稳固,linux内核提供了slab层(也就是所谓的slab分类器),slab分类器扮演了通用数据结构

C/C++Linux、音视频、DPDK 2387

借助ChatGPT完成课题申报书中框架思路写作指南

通过这篇文章的学习,我们可以让ChatGPT先为用户匹配研究理论、研究方法、研究思路、研究内容等,为申请人提供一些参考,能够帮助对拟申报课题有一个初步的认识。当申请人找到了合适的理论、方法和问题后,再借助精细化提示词模型提问,那ChatGPT回答的启发性肯定会有质的提升,更具有使用价值。

智能AI让学术科研更容易 2467

linux slab机制,详解slab机制

目前有很多讲slab的文章,要么是纯讲原理画一堆图结合源码不深导致理解困难,要么是纯代码注释导致理解更困难,我在猛攻了一周时间后,细致总结一下slab,争取从原理到源码都能细致的理解到并立刻达到清楚的使用。一、slab分配器概述:有了伙伴系统buddy,我们可以以页为单位获取连续的物理内存了,即4K为单位的获取,但如果需要频繁的获取/释放并不大的连续物理内存怎么办,如几十字节几百字节的获取/释放,...

weixin_42501785的博客 2976

C#跨平台制图新纪元:Mapsui,一库在手,地图我有

深入学习Mapsui的渲染机制,定制属于你的地图样式,无论是颜色、图标还是文字,都可以随心所欲。

java专栏 1453

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

slab分配器

前面详细讨论了伙伴系统算法,以及基于该算法的页框管理细节。这些内容都是采用页框作为基本内存区,这适合于对大块内存的请求。但是,内核如何处理对一些数据结构分配内存空间,大多数数据结构根本占用不到一个页框。我们如何处理对小内存区的请求呢,比如说几十或几百个字节?显然,如果为了存放很少的字节而给它分配一个整页框,这显然是一种浪费。取而代之的正确方法就是引入一种新的数据结构来描述在同一页框中如何分

云(存储),松(耦合) 1万+

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

上一篇: 内存管理-SLAB(SLAB的基本数据结构)
下一篇: 内存管理-SLAB(销毁SLAB高速缓存kmem_cache_destroy())
白水煮鸡蛋
博客等级 码龄15年 106粉丝 46原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值