0

我编写了自己的 my_malloc() 函数来管理自己的物理内存。在我的应用程序中,我希望能够同时使用 libc malloc() 以及我自己的 my_malloc() 函数。所以我需要对虚拟地址空间进行分区,只有当它来自其专用池时,malloc 才应始终分配一个虚拟地址,与 my_malloc() 相同。我不能限制堆大小,我只需要保证 malloc() 和 my_malloc() 永远不会返回相同/重叠的虚拟地址。

谢谢!

4

4 回答 4

1

一个答案是让你的my_malloc使用内存分配给malloc. 使用足够大的块将主要实现这一点;然后在每个块中,您的版本将维护自己的结构并将其部分分配给调用者。

它变得棘手,因为您不能依赖扩展版本的整个可用空间,就像您从sbrk或类似的地方获取内存时一样。所以你的版本必须维护几个块。

于 2012-05-04T22:27:10.630 回答
1

一种可能性是在启动时my_malloc()调用malloc()以预先分配一个大的内存池,然后将该内存分配给它的调用者并相应地管理它。但是,完整的实现需要处理垃圾收集和碎片整理。

另一种可能性是在每次需要分配内存时my_malloc()调用并简单地处理您感兴趣的任何“簿记”方面,例如分配的块数、释放的块数、最大未完成块、总分配内存。这是迄今为止更安全、更有效的机制,因为您将所有“硬”操作传递给.malloc()malloc()

于 2012-05-04T22:28:36.547 回答
1

保留一大块虚拟地址空间,并将其作为my_malloc()分配的池。一旦您从操作系统保留了一个大的连续内存区域,随后的调用就malloc()必须来自其他地方。

例如,在 Windows 上,您可以使用VirtualAlloc()来保留 256mb 的空间块。在您通过后续调用“提交”它之前,实际上不会分配内存,但它会保留后续malloc()不会使用的地址范围(例如 0x4000000-0x5000000)。然后,您my_malloc()可以根据要求提交此保留范围之外的块,并按您编写的任何分配方案细分它们。

我被告知等效的 Linux 调用是 mmap()。(编辑:我之前说过“kmalloc 或vmalloc,这取决于您是否需要内存在物理上是连续的”,但这些是内核级函数。)

我们在我们的应用程序中使用这种机制将特定大小的所有分配重定向到我们自己的自定义池块分配器中,以提高速度和效率。除其他外,它允许我们保留某些特定大小的虚拟页面,以便CPU 更有效地处理

于 2012-05-04T22:36:23.007 回答
0

如果您mmap(2)在程序开始附近添加一个调用,您可以立即使用所需的任何地址分配所需的内存(请参阅提示,通常留给NULL操作系统确定);这将阻止malloc(3)或任何其他内存分配例程获取这些特定页面。

不用担心内存使用;由于现代系统非常乐意过度使用,因此您只需使用几百 KB 的内核空间来处理页表。还不错。

于 2012-05-04T22:28:50.280 回答