2017-06-02 43 views
1

我有一個創建大量線程的C++應用程序。使用ulimit -v unlimited,創建1080個線程後,應用程序崩潰併發生segfault。當我嘗試訪問分配有「新」的內存時發生崩潰。 「new」返回非空指針,但訪問它會發出段錯誤。 使用ulimit -v 500000,應用程序不會崩潰,但會限制最大線程數(pthread_create失敗 - 行爲要好得多)。 根據上圖,當總內存達到物理RAM的大小時,應用程序崩潰(ulimit -v unlimited)。 我需要~1500個線程(我知道這個缺點......) 根據valgrind的說法,線程非常小,每個線程使用〜16kb的堆棧,所以我不知道爲什麼這麼多的內存被應用佔用。 我可以更改/檢查以減少每線程內存? ulimit -s 1024不起作用。在Linux中減少每個線程的內存

+0

您可以使用'valgrind'和'massif'工具來檢查內存的用途。也有1080線程似乎沒有意義。 – VTT

+0

我沒有使用valgrind一段時間,但請注意堆棧的_used_內存量不一定與堆棧的_reserved_的內存量相同。 –

回答

3

new返回一個非空指針,但在訪問該內存時崩潰的問題是Linux內存過量使用「功能」。 man malloc

默認情況下,Linux遵循樂觀的內存分配策略。這意味着當malloc()返回非NULL時,不能保證內存真的可用。如果事實證明系統內存不足,OOM殺手會殺死一個或多個進程。有關更多信息,請參閱/proc/sys/vm/overcommit_memory/proc/sys/vm/oom_adj的描述,以及proc(5)以及Linux內核源文件Documentation/vm/overcommit-accounting


man pthread_create

在Linux/X86-32,對於一個新的線程默認堆棧大小爲2兆字節。在NPTL線程實現下,如果RLIMIT_STACK軟件資源限制在程序啓動時具有「unlimited」以外的任何值,則它確定新線程的默認堆棧大小。使用pthread_attr_setstacksize(3),可以在用於創建線程的attr參數中顯式設置堆棧大小屬性,以便獲取非默認值的堆棧大小。