2013-03-30 146 views
8

我有几个关于缓冲区和内存池的问题,我想回答。内存池和缓冲区C++

说我有一台服务器,发送和接收〜50-100 + msg /秒。所有消息都有各种大小。你会如何去做这件事来充分利用内存管理?我原来的计划是使用固定大小的缓冲区节点和池他们,是这样的:

struct buffer{ 
    uint8_t data[512]; 
    uint32_t end; 
    buffer* next; 
} 
buffer* b = pool_get_new_buffer(); 

所以当发送味精,我创建取决于大小的一个或多个缓冲区,并将它们连接在一起。这样我就不会害怕游泳池中的碎片。 (或者说,至少我认为)。但在小味精上,它浪费了空间。

但是越来越多的阅读和检查在互联网上的代码,它看起来像没有人使用这种方法。那么更好的方法是什么?根据msg大小从池中分配内存?

编辑: 因此,在这里之后可能会有更多的不同方法比较。

如果我使用链接缓冲区方法即时猜测我会保持在最低的碎片,但另一方面,我会猜测,为链中的每个缓冲区做memcpy也是有代价的。但是,再次分配一个足够大的缓冲区并执行单个memcpy也必须有其缺点,即使大多数人选择这种方法。

+0

你的想法很好。你只需要[扩展](http://en.wikipedia.org/wiki/Buddy_memory_allocation)。您的需求看起来像[general allocator](http://g.oswego.edu/dl/html/malloc.html)。或者如果你需要初始化内存,可能是[SLAB](http://en.wikipedia.org/wiki/Slab_allocation)分配器? –

+0

这不是太流行,因为Linux和BSD已经拥有相当不错的分配器。 Windows默认分配器非常糟糕,但自从MSVC2010发布以来,它们就成为并发CRT的一部分。注意你提到的方案几乎是Linux和BSD在内部用于套接字的一个方案。 –

+0

但为什么它不受欢迎?因为它更难实施?还是因为你这样做没有那么多?如果更具体地了解为什么一种方法比另一种方法更受欢迎会更好。 – user2010820

回答

1

如何拥有一个单一的缓冲区,比如0.5/1MB的大小。这显然取决于目标操作系统/设备以及可能的最大消息大小。另外,让你的服务器包含数据包大小。假设您的数据包没有超过单缓冲区大小,您可以将数据下载到缓冲区中,处理它,然后将内存标记为可用。我已经将这种方法用于单个客户端 - 服务器应用程序。