2013-03-30 143 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的大小。這顯然取決於目標操作系統/設備以及可能的最大消息大小。另外,讓你的服務器包含數據包大小。假設您的數據包沒有超過單緩衝區大小,您可以將數據下載到緩衝區中,處理它,然後將內存標記爲可用。我已經將這種方法用於單個客戶端 - 服務器應用程序。