![]() |
1
0
与其使用手工制作的链表,不如使用
使用两个列表可以大大简化。无需在列表本身中跟踪块是否空闲-因为这将由块在哪个列表中指定(所需的只是确保块不会以某种方式出现在两个列表中)。 您当前的实现意味着您必须在分配和解除分配时遍历链表。
如果块大小是固定的,那么分配将简单地通过将第一个可用块从空闲列表移动到分配列表来实现-无需搜索。要解除分配块,您仍然需要在已分配列表中找到它,这意味着您需要映射
如果块大小可变,则需要做更多的工作。分配将需要在分配时找到至少为请求大小的块。过度分配(分配比需要更大的块)将使分配和释放在性能方面更有效,但也意味着可以从池中分配更少的块。或者,将一大块(从空闲列表中)分成两部分,并在两个列表中放置一个条目(表示已分配的部分和未分配的部分)。如果这样做,在释放时,可能需要合并内存中相邻的块(有效地实现池中空闲内存的碎片整理)。 您需要决定是否可以从多个线程使用池,并使用适当的同步。 |
![]() |
2
0
使用固定数量的大小容器,并使每个容器成为链接列表。 例如,假设您的BIN只是系统页面大小的整数倍(通常为4KB),您使用1MB块;那么您有1MiB/4KiB=256个存储箱。如果一个free使块中的n页区域可用,则将其附加到bin n。分配n页区域时,从n到256遍历bin并选择第一个可用块。 为了最大化性能,将BIN与位图关联,然后从位n-1扫描到位255以找到第一个设置位(使用编译器内部函数(如__builtin_clz和_BitScanForward)计算前导或尾随零)。由于垃圾箱的数量,这仍然不是O(1),但非常接近。 如果您担心内存开销,您可以只附加每个块 一旦 对于每个箱。也就是说,即使一个区块有128个可用的1页区域(最大碎片化),bin 1仍将只链接到该区块一次,并重复使用128次。 要做到这一点,您必须在每个块内将这些区域链接在一起,这意味着每个块还需要存储一个大小容器列表-但这可能更节省内存,因为每个块内最多只有256个有效偏移,而该列表需要存储完整指针。 请注意,无论是哪种方式,如果您不希望每个块中的空闲空间变得零碎,您都需要一种快速的方法从列表中的容器中删除块-这意味着使用双链接列表。显然,这会增加额外的内存开销,但可能仍然比对整个列表进行定期的空闲空间碎片整理更好。 |
![]() |
Community wiki · 如何调试Python内存故障? 1 年前 |
![]() |
tuskiomi · 如何为参考提供明确的锈蚀寿命? 2 年前 |
![]() |
cobb208 · Malloc正在为释放指针引发错误 2 年前 |
![]() |
mo FEAR · C++ STL映射是否在创建后移动了一个值的位置? 2 年前 |
![]() |
Pooyanoss · 覆盖类的堆栈分配实例 2 年前 |
![]() |
TheKing · 为什么数组的地址可以有负值? 3 年前 |
![]() |
Http2inc · 如何从内存中解析这些二进制数据? 3 年前 |
![]() |
tifrel · 如何检查已编译类型的表示形式? 3 年前 |
![]() |
Gabriele · 释放GSL矩阵的正确方法是什么? 6 年前 |
![]() |
Makogan · 3D纹理大小影响程序输出,不会引发错误 6 年前 |