“分配许多相同的对象”是指分配许多相同类型的对象。
为什么在这种情况下我不能使用kmalloc
, kvmalloc
,vmalloc
等?
您可以使用它们,但特殊的缓存分配器(由 创建kmem_cache_create
)有几个优点。其中:
每个对象的内存消耗更少。
当从自己的缓存分配器分配对象时,实际分配的大小可能小于kmalloc
. 这是因为每个缓存分配器只能分配特定大小的对象。
kmalloc
也从缓存分配器分配对象,但它使用预定义大小的分配器。比如说,kmalloc
有 4K 和 8K 尺寸的分配器。当它分配大小为 5K 的对象时,它使用 8K 分配器。那就是3K的分配空间只是浪费。
故障定位。
如果您自己的缓存将被损坏(例如通过double-free),则此损坏将仅影响您自己的对象的分配。其他分配器很有可能保持功能。
更容易调试故障。
如果 Linux 内核报告您自己的缓存分配器损坏,那么您就知道应该从哪里开始调试:很可能是与给定缓存一起工作的代码。
聪明的分配初始化。
分配对象时,您很可能希望它被初始化,即将其字段设置为初始值。通常(使用时)每次分配kmalloc
对象时都需要对其进行初始化。
但是,如果您的对象的字段在您释放对象时具有初始值,那么您不再需要初始化该对象,它会被再次分配。缓存分配器提供了通过其构造函数(ctor
参数)省略已初始化对象的初始化的能力。如果一个对象是第一次分配的,构造函数会被自动调用。如果一个对象之前已被分配(并被释放),则不会调用构造函数。
例如,ext4 文件系统使用构造函数大型复杂文件系统使用构造函数进行分配Linux 内核使用构造函数,例如inodes
当然,当您只需要分配 5 个小对象时,创建分配器会有一点好处:分配器本身会消耗内存,而分配器的创建会消耗时间。
但是如果您需要分配 100 个对象,为它们创建一个分配器将是一个好主意。