0

根据文档(https://www.kernel.org/doc/html/latest/core-api/memory-allocation.html),其中说[强调我的]:

如果你需要分配许多相同的对象,你可以使用slab cache allocator。在使用缓存之前,应该使用 kmem_cache_create() 或 kmem_cache_create_usercopy() 设置缓存。如果缓存的一部分可能被复制到用户空间,则应该使用第二个函数。创建缓存后,kmem_cache_alloc() 及其便利包装器可以从该缓存中分配内存。

“分配许多相同的对象”是什么意思?为什么在这种情况下我不能使用kmalloc,kvmallocvmalloc

4

1 回答 1

2

“分配许多相同的对象”是指分配许多相同类型的对象。

为什么在这种情况下我不能使用kmalloc, kvmalloc,vmalloc等?

您可以使用它们,但特殊的缓存分配器(由 创建kmem_cache_create)有几个优点。其中:

  1. 每个对象的内存消耗更少。

    当从自己的缓存分配器分配对象时,实际分配的大小可能小于kmalloc. 这是因为每个缓存分配器只能分配特定大小的对象。

    kmalloc也从缓存分配器分配对象,但它使用预定义大小的分配器。比如说,kmalloc有 4K 和 8K 尺寸的分配器。当它分配大小为 5K 的对象时,它使用 8K 分配器。那就是3K的分配空间只是浪费。

  2. 故障定位。

    如果您自己的缓存将被损坏(例如通过double-free),则此损坏将仅影响您自己的对象的分配。其他分配器很有可能保持功能。

  3. 更容易调试故障。

    如果 Linux 内核报告您自己的缓存分配器损坏,那么您就知道应该从哪里开始调试:很可能是与给定缓存一起工作的代码。

  4. 聪明的分配初始化。

    分配对象时,您很可能希望它被初始化,即将其字段设置为初始值。通常(使用时)每次分配kmalloc对象时都需要对其进行初始化。

    但是,如果您的对象的字段在您释放对象时具有初始值,那么您不再需要初始化该对象,它会被再次分配。缓存分配器提供了通过其构造函数ctor参数)省略已初始化对象的初始化的能力。如果一个对象是第一次分配的,构造函数会被自动调用。如果一个对象之前已被分配(并被释放),则不会调用构造函数。

    例如,ext4 文件系统使用构造函数大型复杂文件系统使用构造函数进行分配Linux 内核使用构造函数,例如inodes

当然,当您只需要分配 5 个小对象时,创建分配器会有一点好处:分配器本身会消耗内存,而分配器的创建会消耗时间。

但是如果您需要分配 100 个对象,为它们创建一个分配器将是一个好主意。

于 2020-06-20T10:16:10.080 回答