在Linux上,當前地址空間限制可用於人爲地限制進程可以使用的內存量。您可以使用setrlimit(RLIMIT_AS, ...)
手動設置。這也可以使用ulimit -v
爲bashrc
中的整個shell設置。這也可以在整個系統中設置爲/etc/security/limits.conf
。這個地方甚至可能有/ proc/sys條目,我不確定。
如果達到地址空間限制,當您嘗試分配更多內存時,您的進程將拋出std :: bad_alloc。在64位系統上,這可能是一個很好的「安全」,以確保不良應用程序或庫不會使用可用內存,並使系統完全交換或停止工作。確保程序本身不會將其設置在某個位置,並確保其餘環境尚未設置它。你可以在程序的中間插入一些代碼來調用getrlimit(RLIMIT_AS, ...)
以確保它沒有在某個地方潛入。
一個可能更常見的原因(當然,除了實際內存不足外)是一個無符號整數環繞大小寫,其中uin32_t或uint64_t用於分配內存,但是爲0並從中減去1,導致到一個非常大的請求分配(64位將會有數千PB)。
無論如何,最好的方法是跟蹤GDB。如果您的應用程序根本不使用異常(因此根本沒有「catch」語句),那麼您可以啓用核心文件(ulimit -c unlimited
)。下一次程序崩潰時,操作系統將生成一個核心文件,並將其加載到GDB中會立即給你一個回溯,告訴你程序崩潰的位置。
如果你有幾個(但不是很多)使用try的地方,它捕獲這些不良分配,除了在你調試這個問題的時候註釋它們外,你可以在GDB中運行應用程序並使用catch throw
命令每次拋出異常時都讓GDB中斷。對於其中的任何一種工作,請勿使用進行編譯,並始終使用-ggdb
進行編譯(即使使用-O3
)。
自定義分配器在使用中? – sehe
不是我所知道的,或見過的。 –
僅當分配內存失敗時引發bad_alloc,不過正如您所注意的那樣,如果您的程序執行了任何未定義的操作,則可能會執行任何操作,包括在未定義的操作之後隨時拋出bad_alloc –