我正在编写一个意味着在套接字上运行的消息队列,由于各种原因,我希望队列内存存在于用户空间中,并且有一个线程将队列排入各自的套接字。
消息将是一小块内存(可能在4到4K字节之间),所以我认为不断避免malloc()内存是避免碎片的必要条件。
操作模式是用户调用诸如send(msg)之类的东西,然后将消息复制到队列存储器中,并在方便的时候通过套接字发送。
我的问题是,是否存在一种“好的”方法来存储可变大小的数据块,例如std :: queue或std :: vector,或者我将不得不采用将内存池放在一起的路径并处理我自己的分配?
答案 0 :(得分:3)
您可以创建一个大型循环缓冲区,将数据从块复制到该缓冲区,并在队列中存储{start pointer, length}
对。由于块的分配顺序与它们的消耗顺序相同,因此检查重叠的数学运算应该相对简单。
现在内存分配器已经变得相当不错了,所以如果基于“普通”分配器的解决方案表现出相当的性能,我也不会感到惊讶。
答案 1 :(得分:1)
您可以将内存池负担委派给Boost.Pool。
答案 2 :(得分:1)
如果它们低于4K,您可能根本没有碎片。您没有提到要运行应用程序的操作系统,但如果是Linux或Windows,它们可以处理这种大小的块。至少你可以在编写自己的池之前检查一下。例如,请参阅此问题:question about small block allocator
答案 3 :(得分:0)
除非你希望有一个 lot 的排队数据包,否则我可能只会创建一个vector<char>
的池,每个池中都会预留8K。当你完成一个数据包后,回收矢量而不是丢弃它(即把它放回池中,准备再次使用)。
如果你真的确定你的数据包不会超过4K,你可以明显地将它减少到4K而不是8K - 但假设这是一个长期运行的程序,你可能从最小化重新分配获得更多,而不是从最小化单个载体的大小。
一个明显的替代方案是在分配器级别处理此问题,因此您只需重用内存块而不是重用向量。这样可以更轻松地定制内存使用量。我仍然预先分配块,但只有几个大小 - 像64字节,256字节,1K,2K,4K(可能是8K)。