【发布时间】:2014-08-06 10:58:20
【问题描述】:
我正在尝试优化我的动态内存使用情况。问题是我最初为从套接字获得的数据分配了一些内存。然后,在新数据到达时,我正在重新分配内存,因此新到达的部分将适合本地缓冲区。经过一番摸索,我发现 malloc 实际上分配了比请求更大的块。在某些情况下明显更大;这里有一些来自 malloc_usable_size(ptr) 的调试信息:
请求 284 字节,分配 320 字节
请求 644 字节,重新分配 1024 字节
众所周知,malloc/realloc 是昂贵的操作。在大多数情况下,新到达的数据将适合先前分配的块(至少当我请求 644 个字节并获得 1024 个字节时),但我不知道如何弄清楚。
问题是不应该依赖 malloc_usable_size (如手册中所述),如果程序请求 644 字节而 malloc 分配了 1024,则可能会覆盖多余的 644 字节,无法安全使用。因此,使用 malloc 处理给定数量的数据,然后使用 malloc_usable_size 来确定实际分配了多少字节并不是要走的路。
我想要的是在调用 malloc 之前知道块网格,所以我将准确地请求大于我需要的最大字节数,存储分配的大小并在 realloc 上检查我是否真的需要重新分配,或者如果以前分配的块很好,因为它更大。
换句话说,如果我要请求 644 字节,而 malloc 实际上给了我 1024,我希望预测到这一点并请求 1024。
【问题讨论】:
-
这是在哪台电脑上运行的?在过去的二十年里,我没有使用任何计算机/操作系统,我认为这样的重新分配是一项昂贵的操作。您实际测量过需要多长时间吗?
-
我在 Linux 和 FreeBSD 上使用 GCC。
-
您要求的东西不是标准要求的。除此之外,大多数实现分配器使用对齐/页面算法来调整分配大小。如果您想扩展分配有
malloc、calloc或realloc的动态块,请执行您现在正在做的事情:使用realloc()。如果您要扩展的大小已经适合先前分配的页面,则成本将是微不足道的,并且将返回原始指针(同样,这是实践;不是由标准ttbomk)。如果请求的大小太小,无论如何都会进行新的分配+复制。 -
@gnasher729 我认为他的意思是相对于基本操作(例如添加)而言昂贵,而不是绝对时间单位。堆管理例程可能会在 malloc 发生时运行,例如块合并,这可能会导致 malloc 比平时花费更长的时间。
标签: c memory-management malloc