是否有一个 malloc 实现可以在自己的堆之外进行簿记?
我需要管理一个内存堆,限制条件是该内存只能写入,不能读取,即 malloc 实现应该将簿记信息与其管理的堆分开,放在普通堆上,并且实际上永远不应该接触它管理的特定堆。我希望使用一种经过测试、优化、现成的解决方案(如果有的话)。使用示例包括 OpenGL VBO 和嵌入式系统外部单元上的内存。
我看了一眼 dlmalloc,从文档来看,它似乎用簿记信息标记了它从两侧分配的内存块。谷歌搜索也没有任何好处——也许我没有正确的关键字来找到我要找的东西。
澄清:作为一个单独的堆,我的意思是我定义的堆。我想在一个或少量预分配块中严格使用内存并进行少量分配。我什至不关心簿记信息(在托管堆之外)是否大于内部数据:)此外,应用程序本身将使用库存 malloc 和堆进行操作,并且仅将这些块用于特殊目的,这归结为与外部硬件通信的内存区域,其中来自应用程序的写入是目的,读取是不可能的或昂贵的。这不是一个一般的 malloc 问题,我只是希望利用一些已经进行了大量研究和测试的东西。
I need to manage a memory heap, with the constraint that this memory should only be written to, never read, i.e. the malloc implementation should keep the bookkeeping information separately from the heap it manages, on the normal heap, and should in fact never touch the specific heap it manages. I was hoping to use a tested, optimized, off the shelf solution for that, if one is available. Examples of use include OpenGL VBOs and memory on external units of embedded systems.
I glanced at dlmalloc, and from the documentation, it seems to tag the memory blocks it allocates from both sides with bookkeeping information. Googling didn't do any good either - perhaps i don't have the right keywords to find what i'm looking for.
Clarifications: as a separate heap, i mean what i define to be a heap. I want to tightly use memory with small allocations within one or a small number of pre-allocated blocks. I don't even care if the bookkeeping information (outside the thus managed heap) is larger than the data inside :) Furthermore, the application itself will use stock malloc and heap for its operation, and only use those blocks for special purpose, which boils down to memory regions for speaking to external hardware, where writes from application are the purpose, reads are impossible or expensive. This is not a general malloc question, i was merely hoping to leverage something where a lot of research and testing has gone into.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
如果它不管理堆怎么办?请参阅使用特定实现的 malloc 函数,该实现既不管理 [heap] 区域(参见
/proc/$$/maps
),也不将其元数据存储在可寻址内存中,但为您的程序提供了独特的可寻址内存。现在,致命的启示是:glibc 正是使用它来实现足够大的分配。
What if it does not manage the heap? See this malloc function utilizing a particular implementation that neither manages the [heap] area (cf.
/proc/$$/maps
), nor stores its metadata in adressable memory, and yet, gives your program unique adressable memory.And now for the killer revelation: glibc uses exactly that for sufficiently large allocations.
它不是一个现成的库,而是资源管理 Linux 内核中的代码正是执行此操作来管理 PCI 地址空间等资源。
It's not a ready to use library, but the resource management code in the Linux kernel does exactly this to manage resources such as PCI address space.
这是一个非常简单的
malloc
实现,它从不将簿记信息写入它管理的堆中:如果您想要一些更现实的想法,一个简单的解决方案是选择最小的内存单位进行分配(8 或16 字节可能是合理的)并将托管堆划分为该大小的单元,然后将哪些空闲单元存储在位图中(例如,每 16 字节一位,对于 1/128,<1% 开销)。搜索可用空间的时间复杂度为
O(n)
,但您也许可以想办法通过多比例地图来改进它。另一个想法是使用与 dlmalloc 相同的原理,但不是将数据存储在空闲块中,而是对块的地址执行哈希以从哈希箱中获取其簿记信息。然而,任何此类不将信息存储在实际堆中的方法的一个大问题是,释放内存可能会矛盾地增加正在使用的内存量(由于需要分配新的簿记)结构)。
Here's a very simple
malloc
implementation that never writes bookkeeping information to the heap it manages:If you'd like some more realistic ideas, one simple solution is to choose a smallest unit of memory for allocation (8 or 16 bytes might be reasonable) and divide the managed heap into units of this size, then store which ones are free in a bitmap (e.g. one bit per 16 bytes, for 1/128, <1% overhead). Searching for free space is then
O(n)
, but you can think of ways to improve it with multi-scale maps perhaps.Another idea is to use the same principles as dlmalloc, but instead of storing data in the free chunks, perform a hash on a chunk's address to get its bookkeeping information from a hash bin. One big problem with any method like this that doesn't store information in the actual heap, though, is that freeing memory can paradoxically increase the amount of memory in use (due to the need to allocate new bookkeeping structures).
实施起来可能相当简单。不将元数据与分配的块一起存储的一个缺点是 free() 的性能可能会较慢且不确定。但由于 malloc() 已经存在这个问题,也许这并不是真正的问题。
一个简单的确定性解决方案是实现固定块内存分配器,其中从传统堆中分配固定大小的块,并将指向每个块的指针放置在队列或链表上。要分配块,您只需从空闲块队列/列表中获取一个指针,要释放它,您只需将指针放回空闲块列表即可。
An implementation would probably be fairly simple to implement. One disadvantage of not storing the metatdata with the allocated block is that the performance of free() is likley to be slower and non-deterministic. But since malloc() already has that problem, perhaps that is not really an issue.
A simple deterministic solution is to implement a fixed-block memory allocator, where fixed size blocks are allocated from the conventional heap and a pointer to each block is placed on a queue or linked list. To allocate a block you simply take a pointer from the free-block queue/list, and to free it you place the pointer back on the free-block list.
管理器是否需要具有与 malloc/free 相同的语义?如果你可以让你的分配函数返回一个指向结构的指针,而该结构又指向实际的内存,事情将会大大简化;解除分配函数将接受指向结构的指针,而不是指向内存的指针。
除此之外,分配方法将很大程度上受到您的使用模式的影响。关于分配的大小以及分配和释放内存块的模式可以说些什么?
Does the manager need to have the same semantics as malloc/free? Things would be greatly simplified if you could have your allocate function return a pointer to a structure which would in turn point to the actual memory; the deallocate function would accept a pointer to the structure, rather than a pointer to the memory.
Beyond that, the allocation method will be greatly influenced by your usage patterns. What can be said about the sizes of allocations, and the pattern of allocating and freeing memory blocks?
只需使用好友系统即可。
Just use the Buddy System.