[英]How to reduce default C++ memory consumption?
我有一個用C ++編寫的服務器應用程序。 啟動后,它在x86 Linux上使用大約480 KB的內存(Ubuntu 8.04,GCC 4.2.4)。 我認為480 KB是一個過多的內存:服務器甚至沒有做任何事情,沒有客戶端連接到服務器。 (另請參閱下面的評論,其中我解釋了為什么我認為480 KB是大量內存。)服務器在初始化期間唯一做的事情就是產生一個或兩個線程,設置幾個套接字,以及其他簡單的東西。非常記憶密集。
請注意,我在談論實際內存使用情況,而不是VM大小。 我通過在空閑筆記本電腦上啟動我的服務器的100個實例來測量它,並在啟動服務器實例之前和之后用“免費”測量系統內存使用情況。 我已經考慮了文件系統緩存和類似的東西。
經過一些測試后,看起來C ++運行時中的某些東西會導致我的服務器使用這么多內存,即使服務器本身沒有做任何事情。 例如,如果我插入
getchar(); return 0;
之后
int main(int argc, char *argv[]) {
然后每個實例的內存使用量仍為410 KB!
我的應用程序僅依賴於Curl和Boost。 我有很多C編程經驗,我知道C庫在使用之前不會增加內存消耗。
我發現的其他事情:
我的結論如下:
我記得幾年前關於C ++動態鏈接器問題的一些KDE討論。 之后的Linux C ++動態鏈接器導致KDE C ++應用程序啟動時間慢,內存消耗大。 據我所知,這些問題已在C ++運行時修復。 但類似的東西可能是我所看到的過度記憶消耗的原因嗎?
來自gcc /動態鏈接專家的答案非常感謝。
對於那些好奇的人,有問題的服務器是Phusion Passenger的日志記錄代理: https : //github.com/FooBarWidget/passenger/blob/master/ext/common/LoggingAgent/Main.cpp
C運行時分配的內存多於您的進程實際用作正常操作的一部分。 這是因為在內核級別分配內存非常慢,並且只能在頁面大小的塊中完成(x86盒子上的頁面大小通常為4kb,但它可能更大,在x64機器上通常為8kb或更多)。
此外,當C運行時接收到它不能滿足的分配請求時,它通常會分配超過必要的次數,以消除大部分時間進入內核的費用。
最后,如果你正在使用boost goodies,它們可能依賴於某些STL組件,例如std::vector
。 這些組件使用std::allocator<T>
為元素分配空間,在某些情況下,它將再次分配比實際使用的空間更多的空間。 (特別是,基於節點的結構,如std::map
, std::set
和std::list
通常這樣做是為了將列表或樹的節點放在同一個內存頁面上)
長話短說:別擔心。 任何想象力(至少現在)都不會占用半兆內存,而且大部分內存可能只是在分攤動態分配功能的使用。 寫下您的實際服務器,如果它使用了太多內存,那么請查看減少內存使用的方法。
編輯:如果你正在使用的boost組件碰巧是asio,並且你正在使用套接字,你也應該知道為了維護套接字緩沖區而消耗了一些內存。
減少內存消耗的一種方法是減少線程堆棧大小。
關於提升 ,正如Steve Jessop評論的那樣,你必須比“提升”更具體。
聽起來你的某些動態加載庫存在基地址沖突問題。 如果它們在加載期間需要重定位,則它們將作為私有固定副本映射。
重新運行prelink
在您的整個系統。 如果庫加載到其首選地址,它將被映射為共享內存,並且只需要代碼的一個副本,無論有多少進程使用它。
BTW, prelink
也是KDE的修復。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.