2015-06-09 49 views
1

爲什麼在執行gdb調試器中的程序時內存消耗跳躍不可預測?我試圖用gdb來找出爲什麼一個程序使用的內存比它應該多得多,而且它不合作。在gdb中分配內存後

我通過源代碼步驟,同時監視進程的內存使用,但我找不到什麼線(S)分配內存的原因有兩個:

  1. 報告的內存使用率只有在增量跳起來(通常但不總是)64 MB。我懷疑我看到一些內存管理器的效果,我不知道它會一次保留64 MB,並且屏蔽多個較小的分配。
  2. 跳轉不會發生在代碼中的一致位置。不僅在不同的gdb運行期間出現在不同的行上,它也有時發生在不合邏輯的地方,如(C++)函數的右括號。 gdb本身是否可能影響內存分配?

任何關於更有效工具的想法/建議都可以幫助我深入研究真正負責這些內存分配的代碼行嗎?

下面是一些相關的系統信息:我在Windows下的虛擬CentOS Linux機器上運行x86_64-redhat-linux-gnu版本7.2-64.el6-5.2。該程序是通過一個複雜的構建腳本構建在遠程服務器上的,因此,在任何時候確切地跟蹤使用哪些選項本身就是件麻煩事。我使用top實用程序(「virt」或虛擬內存列)以及讀取實時監控文件/proc/<pid>/status來監視內存使用情況,他們同意這一觀點。由於此程序使用大量第三方庫,因此可能會有一個或多個覆蓋的malloc()函數涉及某個我不知道的地方 - 搜索它們是此任務的一部分。

+1

你使用過'valgrind'嗎?這是我調查的第一個停靠港,在'gdb'之前。 –

+0

我們的代碼是用valgrind定期檢查的,儘管我對它不是很熟悉。我認爲這只是尋找內存泄漏(?)我在這裏尋找的東西似乎臃腫,但不漏。 – user2084572

+0

'valgrind'是容器工具;你可以使用'memcheck'組件檢查泄漏情況,但是它的工具集還有更多的功能。這幾乎是一個插件架構。我不確定是否有一個子工具可以實現你想要的功能,但它確實值得檢查。查看博客文章[「Valgrind不是*泄漏檢查器」](http://maintainablecode.logdown.com/posts/245425-valgrind-is-not-a-leak-checker)。 –

回答

1

gdb,留給自己的設備,不會影響程序的內存使用,儘管gdb下的運行可能與其他原因下的獨立運行不同。

但是,這也取決於你使用gdb的方式。如果你只是設置簡單的斷點,步進和打印的東西,那麼你就沒問題。但有時候,爲了評估一個表達式,gdb會在下級分配內存。例如,如果您有像strcmp(arg, "string") == 0這樣的斷點條件,那麼gdb將爲該字符串常量分配內存。還有其他類似的情況。

1

這個答案是在幾個部分,因爲有幾件事情怎麼回事:

  1. Valgrind的與該地塊模塊(內存分析器)比gdb對於這個問題大有幫助。有時用調試器快速瀏覽一下,有時卻不行。 http://valgrind.org/docs/manual/ms-manual.html
  2. top是分析內存使用情況的一個糟糕的工具,因爲它只報告虛擬內存分配,在這種情況下,這個分配大約是實際堆內存使用量的3倍。當進程請求內存塊時,虛擬內存將被映射並由Unix內核提供,但不一定要使用它。底層的系統調用是mmap()。我仍然不知道如何檢查塊大小。 top只能告訴你什麼是Unix內核知道你的內存消耗,這是不夠的幫助。不要使用它(或/ proc /下的內存文件)來執行詳細的內存分析。
  3. 當退出某個函數時,內存分配是由自動鎖定引起的 - 這是一個線程鎖類,當析構函數超出範圍時它會釋放該鎖。然後不同的線程開始行動並分配一些內存,讓操作員(我)迷惑。非重複性可能是因爲一些線程正在等待外部資源,如Internet連接。