图解slub

宋牧春: 多图详解Linux内存分配器slub 本文目录:1. 前言2. slub数据结构3. slub数据结构之间关系4. slub分配内存原理5. slub释放内存原理6. kmalloc作者简介:宋牧春,linux内核爱好者,2017年6月本科毕业于江苏大学。现就职于一家手机研发公司,任职BSP驱动工程师,主要负责TP驱动bringup和调试。1. 前言在Linux中,伙伴系统(buddy system)是以页为单位管理和分配内存。但是现 阅读详情

1.前言

在Linux中,伙伴系统(buddy system)是以页为单位管理和分配内存。但是现实的需求却以字节为单位,假如我们需要申请20Bytes,总不能分配一页吧!那岂不是严重浪费内存。那么该如何分配呢?slab分配器就应运而生了,专为小内存分配而生。slab分配器分配内存以Byte为单位。但是slab分配器并没有脱离伙伴系统,而是基于伙伴系统分配的大内存进一步细分成小内存分配。

前段时间学习了下slab分配器工作原理。因为自己本身是做手机的,发现现在好像都在使用slub分配器,想想还是再研究一下slub的工作原理。之前看了代码,感觉挺多数据结构和成员的。成员的意思是什么?数据结构之间的关系是什么?不知道你是否感觉云里雾里。既然代码阅读起来晦涩难懂,如果有精美的配图,不知是否有助于阁下理解slub的来龙去脉呢?我想表达的意思就是文章图多,图多,图多。我们只说原理,尽量不看代码。因为所有代码中包含的内容我都会用图来说明。你感兴趣绝对有助于你看代码。

说明:slub是slab中的一种,slab也是slab中的一种。有时候用slab来统称slab, slub和slob。slab, slub和slob仅仅是分配内存策略不同。本篇文章中说的是slub分配器工作的原理。但是针对分配器管理的内存,下文统称为slab缓存池。所以文章中slub和slab会混用,表示同一个意思。

注:文章代码分析基于linux-4.15.0-rc3。 图片有点走形,请单独点开图片查看。

 

2. slub数据结构

slub的数据结构相对于slab来说要简单很多。并且对外接口和slab兼容。所以说,从slab的系统更换到slub,可以说是易如反掌。

2.1. kmem_cache

现在假如从伙伴系统分配一页内存供slub分配器管理。对于slub分配器来说,就是将这段连续内存平均分成若干大小相等的object(对象)进行管理。可是我们总得知道每一个object的size吧!管理的内存页数也是需要知道的吧!不然怎么知道如何分配呢!因此需要一个数据结构管理。那就是struct kmem_cache。kmem_cache数据结构描述如下:

  1. struct kmem_cache {
  2. struct kmem_cache_cpu __percpu *cpu_slab;
  3. /* Used for retriving partial slabs etc */
  4. slab_flags_t flags;
  5. unsigned long min_partial;
  6. int size; /* The size of an object including meta data */
  7. int object_size; /* The size of an object without meta data */
  8. int offset; /* Free pointer offset. */
  9. #ifdef CONFIG_SLUB_CPU_PARTIAL
  10. int cpu_partial; /* Number of per cpu partial objects to keep around */
  11. #endif
  12. struct kmem_cache_order_objects oo;
  13. /* Allocation and freeing of slabs */
  14. struct kmem_cache_order_objects max;
  15. struct kmem_cache_order_objects min;
  16. gfp_t allocflags; /* gfp flags to use on each alloc */
  17. int refcount; /* Refcount for slab cache destroy */
  18. void (*ctor)(void *);
  19. int inuse; /* Offset to metadata */
  20. int align; /* Alignment */
  21. int reserved; /* Reserved bytes at the end of slabs */
  22. const char *name; /* Name (only for display!) */
  23. struct list_head list; /* List of slab caches */
  24. struct kmem_cache_node *node[MAX_NUMNODES];
  25. };

1)     cpu_slab:一个per cpu变量,对于每个cpu来说,相当于一个本地内存缓存池。当分配内存的时候优先从本地cpu分配内存以保证cache的命中率。

2)     flags:object分配掩码,例如经常使用的SLAB_HWCACHE_ALIGN标志位,代表创建的kmem_cache管理的object按照硬件cache 对齐,一切都是为了速度。

3)     min_partial:限制struct kmem_cache_node中的partial链表slab的数量。虽说是mini_partial,但是代码的本意告诉我这个变量是kmem_cache_node中partial链表最大slab数量,如果大于这个mini_partial的值,那么多余的slab就会被释放。

4)     size:分配的object size

5)     object_size:实际的object size,就是创建kmem_cache时候传递进来的参数。和size的关系就是,size是各种地址对齐之后的大小。因此,size要大于等于object_size。

6)     offset:slub分配在管理object的时候采用的方法是:既然每个object在没有分配之前不在乎每个object中存储的内容,那么完全可以在每个object中存储下一个object内存首地址,就形成了一个单链表。很巧妙的设计。那么这个地址数据存储在object什么位置呢?offset就是存储下个object地址数据相对于这个object首地址的偏移。

7)     cpu_partial:per cpu partial中所有slab的free object的数量的最大值,超过这个值就会将所有的slab转移到kmem_cache_node的partial链表。

8)     oo:低16位代表一个slab中所有object的数量(oo & ((1 << 16) - 1)),高16位代表一个slab管理的page数量((2^(oo  16)) pages)。

9)     max:看了代码好像就是等于oo。

10)  min:当按照oo大小分配内存的时候出现内存不足就会考虑min大小方式分配。min只需要可以容纳一个object即可。

11)  allocflags:从伙伴系统分配内存掩码。

12)  inuse:object_size按照word对齐之后的大小。

13)  align:字节对齐大小。

14)  name:sysfs文件系统显示使用。

15)  list:系统有一个slab_caches链表,所有的slab都会挂入此链表。

16)  node:slab节点。在NUMA系统中,每个node都有一个struct kmem_cache_node数据结构。

2.2. kmem_cache_cpu

struct kmem_cache_cpu是对本地内存缓存池的描述,每一个cpu对应一个结构体。其数据结构如下: 

  1. struct kmem_cache_cpu {
  2. void **freelist; /* Pointer to next available object */
  3. unsigned long tid; /* Globally unique transaction id */
  4. struct page *page; /* The slab from which we are allocating */
  5. #ifdef CONFIG_SLUB_CPU_PARTIAL
  6. struct page *partial; /* Partially allocated frozen slabs */
  7. #endif
  8. };

1)     freelist:指向下一个可用的object。

2)     tid:一个神奇的数字,主要用来同步作用的。

3)     page:slab内存的page指针。

4)     partial:本地slab partial链表。主要是一些部分使用object的slab。

2.3. kmem_cache_node

slab节点使用struct kmem_cache_node结构体描述。对于slub分配器来说,成员很少,远比slab分配器简洁。

  1. struct kmem_cache_node {
  2. spinlock_t list_lock;
  3. unsigned long nr_partial;
  4. struct list_head partial;
  5. };

1)     list_lock:自旋锁,保护数据。

2)     nr_partial:slab节点中slab的数量。

3)     partial:slab节点的slab partial链表,和struct kmem_cache_cpu的partial链表功能类似。

2.4. slub接口

了解了基本的数据结构,再来看看slub提供的API。如果你了解slub,我想这几个接口你是再熟悉不过了。 

  1. struct kmem_cache *kmem_cache_create(const char *name,
  2. size_t size,
  3. size_t align,
  4. unsigned long flags,
  5. void (*ctor)(void *));
  6. void kmem_cache_destroy(struct kmem_cache *);
  7. void *kmem_cache_alloc(struct kmem_cache *cachep, int flags);
  8. void kmem_cache_free(struct kmem_cache *cachep, void *objp);

1) kmem_cache_create是创建kmem_cache数据结构,参数描述如下:

    name:kmem_cache的名称

    size :slab管理对象的大小

    align:slab分配器分配内存的对齐字节数(以align字节对齐)

    flags:分配内存掩码

    ctor :分配对象的构造回调函数

2) kmem_cache_destroy作用和kmem_cache_create相反,就是销毁创建的kmem_cache。

3) kmem_cache_alloc是从cachep参数指定的kmem_cache管理的内存缓存池中分配一个对象,其中flags是分配掩码,GFP_KERNEL是不是很熟悉的掩码?

4) kmem_cache_free是kmem_cache_alloc的反操作

slab分配器提供的接口该如何使用呢?其实很简单,总结分成以下几个步骤:

1) kmem_cache_create创建一个kmem_cache数据结构。

2) 使用kmem_cache_alloc接口分配内存,kmem_cache_free接口释放内存。

3) release第一步创建的kmem_cache数据结构。

再来一段demo示例代码就更好了。 

  1. /*
  2. * This is a demo for how to use kmem_cache_create
  3. */
  4. void slab_demo(void)
  5. {
  6. struct kmem_cache *kmem_cache_16 = kmem_cache_create("kmem_cache_16", 16,
  7. 8, ARCH_KMALLOC_FLAGS,
  8. NULL);
  9.  
  10. /* now you can alloc memory, the buf points to 16 bytes of memory*/
  11. char *buf = kmeme_cache_alloc(kmem_cache_16, GFP_KERNEL);
  12.  
  13. /*
  14. * do something what you what, don't forget to release the memory after use
  15. */
  16. kmem_cache_free(kmem_cache_16, buf);
  17.  
  18. kmem_cache_destroy(kmem_cache_16);
  19. }

1) 首先使用kmem_cache_create创建名称为kmem_cache_16的kmem_cache,该kmem_cache主要是描述如何管理一堆对象,其实就是slab的布局。每个对象都是16字节,并且分配的对象地址按照8字节对齐,也就是说从kmem_cache_16中分配的对象大小全是16字节。不管你要申请多少,反正就是16Bytes。当然,kmem_cache_create仅仅是创建了一个描述slab缓存池布局的数据结构,并没有从伙伴系统申请内存,具体的申请内存操作是在kmeme_cache_alloc中完成的。

2) kmeme_cache_alloc从kmem_cache_16分配一个对象。

3) 内存使用结束记得kmem_cache_free释放。

4) 如果不需要这个kmem_cache的话,就可以调用kmem_cache_destroy进行销毁吧。在释放kmem_cache之前要保证从该kmem_cache中分配的对象全部释放了,否则无法释放kmem_cache。 

3. slub数据结构之间关系

什么是slab缓存池呢?我的解释是使用struct kmem_cache结构描述的一段内存就称作一个slab缓存池。一个slab缓存池就像是一箱牛奶,一箱牛奶中有很多瓶牛奶,每瓶牛奶就是一个object。分配内存的时候,就相当于从牛奶箱中拿一瓶。总有拿完的一天。当箱子空的时候,你就需要去超市再买一箱回来。超市就相当于partial链表,超市存储着很多箱牛奶。如果超市也卖完了,自然就要从厂家进货,然后出售给你。厂家就相当于伙伴系统。

说了这么多终于要抛出辛辛苦苦画的美图了。

1.png

好了,后面说的大部分内容请看这张图。足以表明数据结构之间的关系了。看懂了这张图,就可以理清数据结构之间的关系了。

3.1. slub管理object方法

在图片的左上角就是一个slub缓存池中object的分布以及数据结构和kmem_cache之间的关系。首先一个slab缓存池包含的页数是由oo决定的。oo拆分为两部分,低16位代表一个slab缓存池中object的数量,高16位代表包含的页数。使用kmem_cache_create()接口创建kmem_cache的时候需要指出obj的size和对齐align。也就是传入的参数。kmem_cache_create()主要是就是填充kmem_cache结构体成员。既然从伙伴系统得到(2^(oo >> 16)) pages大小内存,按照size大小进行平分。一般来说都不会整除,因此剩下的就是图中灰色所示。由于每一个object的大小至少8字节,当然可以用来存储下一个object的首地址。就像图中所示的,形成单链表。图中所示下个obj地址存放的位置位于每个obj首地址处,在内核中称作指针内置式。同时,下个obj地址存放的位置和obj首地址之间的偏移存储在kmem_cache的offset成员。两外一种方式是指针外置式,即下个obj的首地址存储的位置位于obj尾部,也就是在obj尾部再分配sizeof(void *)字节大小的内存。对于外置式则offset就等于kmem_cache的inuse成员。

3.2. per cpu freelist

针对每一个cpu都会分配一个struct kmem_cacche_cpu的结构体。可以称作是本地缓存池。当内存申请的时候,优先从本地cpu缓存池申请。在分配初期,本地缓存池为空,自然要从伙伴系统分配一定页数的内存。内核会为每一个物理页帧创建一个struct page的结构体。kmem_cacche_cpu中page就会指向正在使用的slab的页帧。freelist成员指向第一个可用内存obj首地址。处于正在使用的slab的struct page结构体中的freelist会置成NULL,因为没有其他地方使用。struct page结构体中inuse代表已经使用的obj数量。这地方有个很有意思的地方,在刚从伙伴系统分配的slab的 inuse在分配初期就置成obj的总数,在分配obj的时候并不会改变。你是不是觉得很奇怪,既然表示已经使用obj的数量,为什么一直是obj的总数呢?你想想,slab中的对象总有分配完的时候,那个时候就直接脱离kmem_cache_cpu了。此时的inuse不就名副其实了嘛!对于full slab就像图的右下角,就像无人看管的孩子,没有任何链表来管理。

3.3. per cpu partial

当图中右下角full slab释放obj的时候,首先就会将slab挂入per cpu partial链表管理。通过struct page中next成员形成单链表。per cpu partial链表指向的第一个page中会存放一些特殊的数据。例如:pobjects存储着per cpu partial链表中所有slab可供分配obj的总数,如图所示。当然还有一个图中没有体现的pages成员存储per cpu partial链表中所有slab缓存池的个数。pobjects到底有什么用呢?我们从full slab中释放一个obj就添加到per cpu partial链表,总不能无限制的添加吧!因此,每次添加的时候都会判断当前的pobjects是否大于kmem_cache的cpu_partial成员,如果大于,那么就会将此时per cpu partial链表中所有的slab移送到kmem_cache_node的partial链表,然后再将刚刚释放obj的slab插入到per cpu partial链表。如果不大于,则更新pobjects和pages成员,并将slab插入到per cpu partial链表。

3.4. per node partial

per node partia链表类似per cpu partial,区别是node中的slab是所有cpu共享的,而per cpu是每个cpu独占的。假如现在的slab布局如上图所示。假如现在如红色箭头指向的obj将会释放,那么就是一个empty slab,此时判断kmem_cache_node的nr_partial是否大于kmem_cache的min_partial,如果大于则会释放该slab的内存。 

 

4. slub分配内存原理

当调用kmem_cache_alloc()分配内存的时候,我们可以从正在使用slab分配,也可以从per cpu partial分配,同样还可以从per node partial分配,那么分配的顺序是什么呢?我们可以用下图表示。

2.png

首先从cpu 本地缓存池分配,如果freelist不存在,就会转向per cpu partial分配,如果per cpu partial也没有可用对象,继续查看per node partial,如果很不幸也不没有可用对象的话,就只能从伙伴系统分配一个slab了,并挂入per cpu freelist。我们详细看一下这几种情况。

1)     kmem_cache刚刚建立,还没有任何对象可供分配,此时只能从伙伴系统分配一个slab,如下图所示。

3.png

3.png

2)     如果正在使用的slab有free obj,那么就直接分配即可,这种是最简单快捷的。如下图所示。

4.png

3)     随着正在使用的slab中obj的一个个分配出去,最终会无obj可分配,此时per cpu partial链表中有可用slab用于分配,那么就会从per cpu partial链表中取下一个slab用于分配obj。如下图所示。

5.png

4)     随着正在使用的slab中obj的一个个分配出去,最终会无obj可分配,此时per cpu partial链表也为空,此时发现per node partial链表中有可用slab用于分配,那么就会从per node partial链表中取下一个slab用于分配obj。如下图所示。

6.png

 

5. slub释放内存原理

我们可以通过kmem_cache_free()接口释放申请的obj对象。释放对象的流程如下图所示。

7.png

如果释放的obj就是属于正在使用cpu上的slab,那么直接释放即可,非常简单;如果不是的话,首先判断所属slub是不是full状态,因为full slab是没妈的孩子,释放之后就变成partial empty,急需要找个链表领养啊!这个妈就是per cpu partial链表。如果per cpu partial链表管理的所有slab的free object数量超过kmem_cache的cpu_partial成员的话,就需要将per cpu partial链表管理的所有slab移动到per node partial链表管理;如果不是full slab的话,继续判断释放当前obj后的slab是否是empty slab,如果是empty slab,那么在满足kmem_cache_node的nr_partial大于kmem_cache的min_partial的情况下,则会释放该slab的内存。其他情况就直接释放即可。

1)     假设下图左边的情况下释放obj,如果满足kmem_cache_node的nr_partial大于kmem_cache的min_partial的话,释放情况如下图所示。

8.png

 

2)     假设下图左边的情况下释放obj,如果不满足kmem_cache_node的nr_partial大于kmem_cache的min_partial的话,释放情况如下图所示。

9.png

 

3)     假设下图从full slab释放obj的话,如果满足per cpu partial管理的所有slab的free object数量大于kmem_cache的cpu_partial成员的话的话,将per cpu partial链表管理的所有slab移动到per node partial链表管理,释放情况如下图所示。

10.png

 

4)     假设下图从full slab释放obj的话,如果不满足per cpu partial管理的所有slab的free object数量大于kmem_cache的cpu_partial成员的话的话,释放情况如下图所示。

11.png

 

6. kmalloc

好了,说了这么多,估计你会感觉slab好像跟我们没什么关系。如果作为一个驱动开发者,是不是感觉自己写的driver从来没有使用过这些接口呢?其实我们经常使用,只不过隐藏在kmalloc的面具之下。

kmalloc的内存分配就是基于slab分配器,在系统启动初期调用create_kmalloc_caches ()创建多个管理不同大小对象的kmem_cache,例如:8B、16B、32B、64B、…、64MB等大小。当然默认配置情况下,系统系统启动之后创建的最大size的kmem_cache是kmalloc-8192。因此,通过slab接口分配的最大内存是8192 bytes。那么通过kmalloc接口申请的内存大于8192 bytes该怎么办呢?其实kmalloc会判断申请的内存是否大于8192 bytes,如果大于的话就会通过alloc_pages接口申请内存。kmem_cache的名称以及大小使用struct kmalloc_info_struct管理。所有管理不同大小对象的kmem_cache的名称如下: 

  1. const struct kmalloc_info_struct kmalloc_info[] __initconst = {
  2. {NULL, 0}, {"kmalloc-96", 96},
  3. {"kmalloc-192", 192}, {"kmalloc-8", 8},
  4. {"kmalloc-16", 16}, {"kmalloc-32", 32},
  5. {"kmalloc-64", 64}, {"kmalloc-128", 128},
  6. {"kmalloc-256", 256}, {"kmalloc-512", 512},
  7. {"kmalloc-1024", 1024}, {"kmalloc-2048", 2048},
  8. {"kmalloc-4096", 4096}, {"kmalloc-8192", 8192},
  9. {"kmalloc-16384", 16384}, {"kmalloc-32768", 32768},
  10. {"kmalloc-65536", 65536}, {"kmalloc-131072", 131072},
  11. {"kmalloc-262144", 262144}, {"kmalloc-524288", 524288},
  12. {"kmalloc-1048576", 1048576}, {"kmalloc-2097152", 2097152},
  13. {"kmalloc-4194304", 4194304}, {"kmalloc-8388608", 8388608},
  14. {"kmalloc-16777216", 16777216}, {"kmalloc-33554432", 33554432},
  15. {"kmalloc-67108864", 67108864}
  16. };

经过create_kmalloc_caches ()函数之后,系统通过create_kmalloc_cache()创建以上不同size的kmem_cache,并将这些kmem_cache存储在kmalloc_caches全局变量中以备后续kmalloc分配内存。现在假如通过kmalloc(17, GFP_KERNEL)申请内存,系统会从名称“kmalloc-32”管理的slab缓存池中分配一个对象。即使浪费了15Byte。

我们来看看kmalloc的实现方式。 

  1. static __always_inline void *kmalloc(size_t size, gfp_t flags)
  2. {
  3. if (__builtin_constant_p(size)) {
  4. if (size > KMALLOC_MAX_CACHE_SIZE)
  5. return kmalloc_large(size, flags);
  6. if (!(flags & GFP_DMA)) {
  7. int index = kmalloc_index(size);
  8. if (!index)
  9. return ZERO_SIZE_PTR;
  10. return kmem_cache_alloc_trace(kmalloc_caches[index], flags, size);
  11. }
  12. }
  13. return __kmalloc(size, flags);
  14. }

1)     __builtin_constant_p是gcc工具用来判断参数是否是一个常数,毕竟有些操作对于常数来说是可以优化的。

2)     通过kmalloc_index函数查找符合满足分配大小的最小kmem_cache。

3)     将index作为下表从kmalloc_caches数组中找到符合的kmem_cache,并从slab缓存池中分配对象。

我们再看一下kmalloc_index的实现。 

  1. static __always_inline int kmalloc_index(size_t size)
  2. {
  3. if (!size)
  4. return 0;
  5. if (size <= KMALLOC_MIN_SIZE)
  6. return KMALLOC_SHIFT_LOW;
  7. if (KMALLOC_MIN_SIZE <= 32 && size > 64 && size <= 96)
  8. return 1;
  9. if (KMALLOC_MIN_SIZE <= 64 && size > 128 && size <= 192)
  10. return 2;
  11. if (size <= 8) return 3;
  12. if (size <= 16) return 4;
  13. if (size <= 32) return 5;
  14. if (size <= 64) return 6;
  15. if (size <= 128) return 7;
  16. if (size <= 256) return 8;
  17. if (size <= 512) return 9;
  18. if (size <= 1024) return 10;
  19. if (size <= 2 * 1024) return 11;
  20. if (size <= 4 * 1024) return 12;
  21. if (size <= 8 * 1024) return 13;
  22. if (size <= 16 * 1024) return 14;
  23. if (size <= 32 * 1024) return 15;
  24. if (size <= 64 * 1024) return 16;
  25. if (size <= 128 * 1024) return 17;
  26. if (size <= 256 * 1024) return 18;
  27. if (size <= 512 * 1024) return 19;
  28. if (size <= 1024 * 1024) return 20;
  29. if (size <= 2 * 1024 * 1024) return 21;
  30. if (size <= 4 * 1024 * 1024) return 22;
  31. if (size <= 8 * 1024 * 1024) return 23;
  32. if (size <= 16 * 1024 * 1024) return 24;
  33. if (size <= 32 * 1024 * 1024) return 25;
  34. if (size <= 64 * 1024 * 1024) return 26;
  35. /* Will never be reached. Needed because the compiler may complain */
  36. return -1;
  37. } 
Linux内存管理 内存检测技术(slub_debug/kmemleak/kasan) https://www.cnblogs.com/arnoldlu/p/8568090.html Linux常见的内存访问错误有: 越界访问(out of bounds) 访问已经释放的内存(use after free) 重复释放 内存泄露(memory leak) 栈溢出(stack overflow) 不同的工具有不同的侧重点,本章主要从slub_debug、kmemleak、kasan三个工具介绍。 kmemleak侧重于内存泄露问题发现。 slub_debug和kasan有一定的重复,部分slub_ 阅读详情

相关推荐

Linux SLUB 分配器详解

多年以来,Linux 内核使用一种称为 SLAB 的内核对象缓冲区分配器。但是,随着系统规模的不断增大,SLAB 逐渐暴露出自身的诸多不足。SLUB 是 Linux 内核 2.6.22 版本中引入的一种新型分配器,它具有设计简单、代码精简、额外内存占用率小、扩展性高,性能优秀、方便调试等特点。本文先介绍 SLAB 分配器的基本原理,然后分析其不足之处并详细介绍 SLUB 的设计思想,最后介绍 SL

tianyu的专栏 - Linux site:blog.youkuaiyun.com/wishfly 1530

Linux 内存管理之 SLUB分配器(2) :kmalloc_cache 结构

1. slub 2. kmalloc_caches、kmem_cache数据结构 3. 分配逻辑

And乔的博客 2128

密码学新手必看:三大顶级会议论文下载与阅读指南(附完整资源链接)

本文为密码学新手提供了系统性的三大顶级会议(Crypto、Eurocrypt、Asiacrypt)论文学习指南。内容涵盖如何高效获取最新论文资源、结构化精读论文的方法论,以及将理论转化为代码实践的路径,旨在帮助初学者快速构建密码学知识体系并应用于研究。

weixin_29214691的博客 319

linux 内核 内存管理 slub算法 (一) 原理

内核管理页面使用了2个算法:伙伴算法和slub算法,伙伴算法以页为单位管理内存,但在大多数情况下,程序需要的并不是一整页,而是几个、几十个字节的小内存。于是需要另外一套系统来完成对小内存的管理,这就是slub系统。slub系统运行在伙伴系统之上,为内核提供小内存管理的功能。         slub把内存分组管理,每个组分别包含2^3、2^4、...2^11个字节,在4K页大小的默认情况下,另外

卢坤的专栏 2万+

DRAM 埋入式字线(Buried Wordline)技术深度解析:从二维平面到三维凹槽

埋入式字线(bWL)及其核心的埋入式沟道阵列晶体管(BCAT)架构,无疑是 DRAM 发展史上的一次关键性革命。它在约 40nm 技术节点被行业主流采纳,成功地帮助 DRAM 产业克服了传统平面晶体管的物理缩放极限。力挽狂澜的续命技术:bWL 通过引入三维沟道结构,从根本上解决了由短沟道效应和漏电流失控引发的数据保持危机,为经典的 1T1C(单晶体管 - 单电容)DRAM 单元架构延续了超过十年的生命力。协同优化的基石技术。

m0_37606066的博客 3329

2023 ICRA《Visual Language Maps for Robot Navigation》阅读笔记

视觉语言导航可以使用预先训练的现有的视觉语言模型来将图像与对象目标的自然语言描述相匹配,但它与绘制环境的过程仍然脱节,缺乏经典几何地图的空间精度。为了解决这个问题,我们提出了VLMaps,这是一种空间地图表示,它将预训练的视觉语言特征与物理世界的3D重建直接融合在一起。VLMaps可以使用标准探索方法从机器人上的视频馈送中自主构建,并在没有额外标记数据的情况下实现地图的自然语言索引。具体来说,当与大型语言模型(LLM)相结合时,VLMaps可以用于。

qq_44100524的博客 1990

详解slab机制

http://blog.csdn.net/u010246947/article/details/10133101 目前有很多讲slab的文章,要么是纯讲原理画一堆图结合源码不深导致理解困难,要么是纯代码注释导致理解更困难,我在猛攻了一周时间后,细致总结一下slab,争取从原理到源码都能细致的理解到并立刻达到清楚的使用。 一、slab分配器概述: 有了伙伴系统buddy,我们可以以页为单位获取

cosmoslhf的专栏 1万+

【ComfyUI】Z-Image 基础文生图 + 单LoRA

本文介绍了一个基于ComfyUI的Z-Image Turbo基础文生图工作流,采用轻量化UNet模型配合Qwen Image文本理解模型与LoRA风格注入,实现从文本到图像的快速生成。工作流结构清晰,包含模型加载、文本编码、采样解码等标准节点,在人物生成、构图稳定性和出图速度方面表现均衡。通过调整Prompt可控制生成内容,适合日常创作、教学演示及扩展进阶应用。

Mr数据杨 926

linux的slub算法原理,图解slub

图解slub作者:smcdef 发布于:2018-2-22 21:02分类:内存管理1.前言在Linux中,伙伴系统(buddy system)是以页为单位管理和分配内存。但是现实的需求却以字节为单位,假如我们需要申请20Bytes,总不能分配一页吧!那岂不是严重浪费内存。那么该如何分配呢?slab分配器就应运而生了,专为小内存分配而生。slab分配器分配内存以Byte为单位。但是slab分配器并...

weixin_35748716的博客 1184

基于YOLOv5/v8/v10的垃圾分类识别系统:设计实现与性能优化(附代码+数据集)

做完这个毕设,你已经掌握了从数据准备、模型训练到界面开发的全流程。把模型部署到树莓派上,做个真正的“智能垃圾桶”硬件装置;加入语音提示功能,检测到垃圾后自动语音播报类别;试试融合多个YOLO模型的优势,让分类精度再上一个台阶。按照这个教程一步步做,你的毕设不仅能顺利完成,还能做出很多亮点。要是过程中遇到啥问题,别慌,慢慢琢磨或者咱们一起聊聊,肯定能把这个毕设做成让你满意的作品。

know_F0727的博客 463

如何从 VMware 官网下载最新版本的 VMware Workstation

如何从 VMware 官网下载 VMware Workstation

XiaoqiangClub的博客 5906

图解SLUB

1.前言 在Linux中,伙伴系统(buddy system)是以页为单位管理和分配内存。但是现实的需求却以字节为单位,假如我们需要申请20Bytes,总不能分配一页吧!那岂不是严重浪费内存。那么该如何分配呢?slab分配器就应运而生了,专为小内存分配而生。slab分配器分配内存以Byte为单位。但是slab分配器并没有脱离伙伴系统,而是基于伙伴系统分配的大内存进一步细分成小内存分配。 前段时间学...

春花秋月何时了?往事知多少 463

Openlayers 教程 02 - 地图添加 WKT WKB GeoJson 格式的点线面数据

WebGIS 开发中,对于数据量不是很大的场景,可以直接从数据库读取数据,通过创建点线面要素(Feature),然后添加到矢量图层(vectorLayer)中,在地图上展示。添加点线面的方法可以封装一下,方便使用。...

非科班Java出身GISer的博客 3856

slub机制彻底图解分析

内核管理页面使用了2个算法:伙伴算法和slub算法,伙伴算法以页为单位管理内存,但在大多数情况下,程序需要的并不是一整页,而是几个、几十个字节的小内存。于是需要另外一套系统来完成对小内存的管理,这就是slub系统。slub系统运行在伙伴系统之上,为内核提供小内存管理的功能。         slub把内存分组管理,每个组分别包含2^3、2^4、...2^11个字节,在4K页大小的默认情况下,另外

FreeeLinux's blog 7774

Open3D点云数据处理(六):点云、mesh可视化(Visualizer类)

本文介绍了Open3D中Visualizer类可视化几何对象的方法,给出了常用参数解释和代码示例。

孙悟空 3025

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

图解slub内存分配器

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33895475的博客 461

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

linux sl(aou)b原理文章记录

linux 内核 内存管理 slub算法 (一) 原理https://blog.csdn.net/lukuen/article/details/6935068 图解slubhttp://www.wowotech.net/memory_management/426.html linux内存源码分析 - SLAB分配器概述:https://www.cnblogs.com/tolimit...

qq_30025621的博客 263

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

SLUB的引入及举例说明

我们都知道Buddy分配器是按照页的单位分配的(Buddy系统分配器实现),如果我们需要分配几十个字节,几百个字节的时候,就需要用到SLAB分配器。 SLAB分配器专门是针对小内存分配而设计的,比如我们驱动中常见的Kmalloc分配器就是通过SLAB分配器分配的内存。 而SLAB分配器在linux系统中三种具体的实现:SLAB,SLUB,SLOB。目前内核代码中默认的SLAB分配器为SLUB算...

半月旋空 1452

Slub分配器的来龙去脉

slab分配器设计的需求在Linux内核的内存子系统中,伙伴系统无疑处于内存管理的核心地带,但是如果将内存管理从逻辑上分层,它的位置则处于最底层。Buddy是所有物理内存的管家,不论使用何种接口申请内存都要经由伙伴系统进行分配。但是,伙伴系统管理的物理内存是以页为单位,以4K页为例,它也包含了4096个字节。但是无论是内核自己还是用户程序,在日常的使用中都很少会需要使用四...

Peter的专栏 884

Linux内存管理 (22)内存检测技术(slub_debug/kmemleak/kasan)

https://www.cnblogs.com/arnoldlu/p/8568090.html 专题:Linux内存管理专题 关键词:slub_debug、kmemleak、kasan、oob、Redzone、Padding。 Linux常见的内存访问错误有: 越界访问(out of bounds) 访问已经释放的内存(use after free) 重复释放 内存泄露(memory leak) ...

hbcbgcx的博客 1945

内存检测技术(slub_debug/kmemleak/kasan)

关键词:slub_debug、kmemleak、kasan、oob、Redzone、Padding。   Linux常见的内存访问错误有: 越界访问(out of bounds) 访问已经释放的内存(use after free) 重复释放 内存泄露(memory leak) 栈溢出(stack overflow) 不同的工具有不同的侧重点,本章主要从slub_debug、kmemleak、kasan三个工具介绍。 kmemleak侧重于内存泄露问题发现。 slub_debug和kasan有一

biaotai的博客 2153

Linux内存管理 (22)内存检测技术(slub_debug/kmemleak/kasan)【转】

转自:https://www.cnblogs.com/arnoldlu/p/8568090.html 专题:Linux内存管理专题 关键词:slub_debug、kmemleak、kasan、oob、Redzone、Padding。 Linux常见的内存访问错误有: 越界访问(out of bounds) 访问已经释放的内存(use after free) 重复释放 ...

weixin_34245749的博客 598
上一篇: 漫画:什么是 “哈夫曼树” ?
下一篇: SLUB DEBUG原理
废言Pro
博客等级 码龄16年 1093粉丝 142原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值