2010-09-06 89 views
0

我使用Linux for ARM處理器進行線纜調制解調器。我寫了一個工具,它使用原始套接字發送/暴發定製的UDP數據包。我從零開始構建數據包,以便我們可以靈活地使用不同的選項。這個工具主要用於壓力測試路由器。子進程的內存優化

我實際上已經創建了多個接口。每個接口將使用DHCP獲取IP地址。這是爲了使調制解調器像虛擬客戶端設備(vcpe)一樣工作。

當系統啓動時,我啓動要求的那些進程。我開始的每個過程都會不斷髮送數據包。因此進程0將使用接口0發送數據包等。每個發送數據包的進程都允許進行配置(在運行時更改UDP參數和其他選項)。這就是我決定分開處理的原因。

我使用fork和excec從調制解調器的調配過程開始這些過程。

現在的問題是每個進程佔用大量內存。只啓動3個這樣的進程,導致系統崩潰並重啓。

我曾嘗試以下:

我一直認爲推動更多的代碼共享庫會有所幫助。所以當我嘗試將許多函數移動到共享庫中並在進程中保留最小代碼時,我感到意外並沒有什麼區別。我還刪除了所有數組,並使它們使用堆。但它沒有區別。這可能是因爲進程持續運行,如果它是堆棧或堆沒有區別?我懷疑我從哪裏調用fork的過程是巨大的,這就是我使得結果很大的過程的原因。我不知道我還能如何去做。說過程A是巨大的 - >我通過分叉和excec來啓動過程B. B繼承了A的內存區域。所以,現在我這樣做 - > A啓動C,它啓動B也不會幫助,因爲C仍然繼承A ?.我用vfork作爲一種替代方法,也沒有幫助。我想知道爲什麼。

如果有人給我提示,以幫助我減少每個獨立子進程使用的內存,我將不勝感激。

回答

2

鑑於這是一個測試工具,那麼最有效的做法是向測試機器添加更多內存。

做不到這一點:

  1. 您如何測量內存使用情況?有些方法無法獲得準確的結果。
  2. 檢查你沒有任何內存泄漏。例如在Linux x86上使用Valgrind。
  3. 你可以嘗試在單個進程中運行不同的測試器,因爲不同的線程,甚至在一個線程中複用 - 因爲網絡應該是限制因素?
  4. 當新的執行得到一個新的內存映射時,exec()會縮小進程的內存大小。
  5. 如果你不能添加物理內存,那麼也許你可以添加交換,也許只是爲了測試?
1

技術上不回答你的問題,但提供了幾個備選解決方案:如果你有考慮過使用pktgen使用Linux

?它是一種靈活的工具,可以儘可能快地從內核發送UDP數據包。這比用戶空間工具快得多。

哦,一個無恥的插頭。我製作了一個multi-threaded network testing tool,它可以用來通過UDP數據包發送垃圾郵件。它可以以多進程模式(通過使用fork)或多線​​程模式(使用pthread)運行。 pthreads可能會使用更少的RAM,所以對您來說可能會更好。如果有什麼值得一看的話,我可以花多年的時間來改進這個代碼,並且它能夠生成足夠的數據包來飽和一個10Gbps的接口。

1

可能發生的情況是進程A中的fork調用需要大量的RAM + swap(如果有)。因此,當你從這個進程調用fork()時,內核必須爲子進程保留足夠的RAM和交換,以便擁有它自己的父進程的可寫私有內存副本(實際上是寫時拷貝),即堆棧和堆。當您從子進程調用exec()時,不再需要該內存,並且您的子進程可以擁有它自己的較小的私有工作集。

因此,首先要確定的是,在fork()和exec()之間的狀態中,一次沒有多個進程。在此狀態期間,子進程必須具有其父進程虛擬內存空間的副本。

其次,嘗試使用overcommit設置,這將允許內核保留比實際存在更多的內存。這些是/ proc/sys/vm/overcommit *。你可以放棄使用overcommit,因爲你的子進程只需要額外的虛擬機空間,直到他們調用exec,並且實際上不應該觸及父進程的重複地址空間。

第三,在您的父進程中,您可以使用共享內存而不是堆棧或堆來分配最大的塊,這些塊是私有的。因此,當你分叉時,這些共享內存區域將與子進程共享,而不是重複寫時拷貝。