我添加了一個在我的C++程序代碼中重新啓動的選項。每次重新啓動時,我都可以看到駐留內存增加,而valgrind沒有顯示任何泄漏。什麼可能是居民記憶增加的原因。駐留內存增加,而valgrind沒有顯示任何泄漏
回答
這有幾個可能的原因:
- 你可能會越來越多的內存,但實際上沒有泄漏:像
vector<int> v; for(;;) v.push_back(1);
的事情會在幾秒鐘內耗盡內存,但不是泄漏根據的valgrind 。 - 堆是你的「資源」記憶的一部分,所以如果你有一些分配X堆內存的MB,然後將其釋放,除非操作系統實際需要內存用於其他目的,它會留在你的應用程序的一部分記憶。 (實際上,它比這更復雜一點,但對於這個討論,這張圖片是有效的)。
- 堆碎片。如果你在堆中分配和釋放內存,並且內存大小變化很大,那麼內存確實是「免費的」,但堆中的塊可能太小而不能用於下一次分配,因此「新鮮」堆被切斷。想象一下,你從一塊長長的木頭開始,將它剪下來以適應某個地方,然後將其取下並再次切割 - 你再也不能將它恢復成全尺寸。 (再次,實際上,這比這更復雜,但對於這個討論來說就足夠了)。
您可能想要使用valgrind的地塊工具,valgrind --tool=massif prog
來識別#1等數據隨時間推移而建立的事物。
編輯: 從鏈接的網頁:
地塊是一個堆分析器。它會測量您的 程序使用多少堆內存。這包括有用的空間和分配用於簿記和對齊目的的額外字節 。它也可以測量你的程序堆棧的大小,儘管 默認值沒有這樣做。
mem_heap_extra_B
是分配爲「填充」和「開銷」的字節數。它通常只佔總分配大小的一小部分,但如果你有很多非常小的分配,它可以支配堆的使用。
mem_stacks_B
是應用程序使用的堆棧的字節數(默認情況下,這不是測量的,因爲它會顯着降低代碼的速度)。
取本程序作爲一個例子:
#include <vector>
int main(int argc, char **argv)
{
(void)argv; // Not used.
const int size = 10000;
std::vector<int*> v(size);
switch (argc)
{
case 1:
for(int i = 0; i < size; i++)
{
v[i] = new int;
};
for(int i = 0; i < size; i++)
{
delete v[i];
};
break;
case 2:
{
int *t = new int [size];
for(int i = 0; i < size; i++)
{
v[i] = t+i;
};
delete [] t;
break;
}
}
return 0;
}
以下是從valgrind --tool=massif ./a.out
(所以case 1:
變體的代碼)的輸出端(在高峯使用):
time=2872338
mem_heap_B=120000
mem_heap_extra_B=200008
mem_stacks_B=0
heap_tree=peak
其中如果我們與valgrind --tool=massif ./a.out 1
(所以case 2:
criant代碼的)運行時,在高峯使用時,輸出的是:
time=2523909
mem_heap_B=120000
mem_heap_extra_B=16
mem_stacks_B=0
heap_tree=peak
請注意mem_heap_extra_B
在第一種情況下的差異是多大於實際的堆使用量(因爲每4個字節的分配實際上佔用了很多),在第二種情況下,額外的字節只有16個,但堆的實際「已用」大小是相同的,120000(這是有道理的,我們有8個字節10000個指針,每個4個字節+ 10000個整數)。
不幸的是,這個程序是相當無趣,當談到疊加使用,但如果你使用--stacks=yes
,它會顯示使用的堆棧的字節數,如:
time=2222719
mem_heap_B=120000
mem_heap_extra_B=16
mem_stacks_B=528
如果我在grep命令查找mem_stacks_B
在Pascal編譯器我的工作,那麼它變得更有趣:
10:mem_stacks_B=0
18:mem_stacks_B=1576
26:mem_stacks_B=1368
34:mem_stacks_B=1368
42:mem_stacks_B=1576
50:mem_stacks_B=120
58:mem_stacks_B=2592
66:mem_stacks_B=4656
288:mem_stacks_B=2464
296:mem_stacks_B=43104
431:mem_stacks_B=2424
439:mem_stacks_B=10960
447:mem_stacks_B=8096
622:mem_stacks_B=8352
887:mem_stacks_B=3816
895:mem_stacks_B=3360
903:mem_stacks_B=3664
911:mem_stacks_B=3216
有很多多,但足以說明「堆棧使用變化頗有幾分」。
正如你所看到的,它變化很大。不,我沒有試圖弄清楚它在使用43KB堆棧時的作用 - 反正它並不是真正的無用。
- 1. setpwent在valgrind中顯示內存泄漏
- 2. C++:當駐留內存緩慢增加時是否存在內存泄漏?
- 3. valgrind沒有發現內存泄漏?
- 4. 沒有valgrind的內存泄漏狩獵
- 5. Valgrind內存泄漏可達
- 6. 內存泄漏(Valgrind的)
- 7. Valgrind修復內存泄漏
- 8. getline()valgrind內存泄漏
- 9. Valgrind的和內存泄漏
- 10. 當valgrind說沒有內存泄漏時內存泄漏的機會
- 11. 跟蹤valgrind內存泄漏的提示
- 12. 如何強制valgrind只顯示內存泄漏?
- 13. valgrind如何檢測內存泄漏
- 14. 即使沒有內存泄漏,Windows任務管理器也會顯示進程內存不斷增加
- 15. JSONValue顯示內存泄漏
- 16. Can Valgrind可以顯示泄漏內存的值嗎?
- 17. Valgrind顯示內存泄漏,現在是什麼? R:C()擴展
- 18. 由valgrind顯示的內存泄漏到gtk初始化調用
- 19. Valgrind的報告內存泄漏雖然沒有一個並[c]
- 20. gsoap/valgrind;沒有泄漏,但內存錯誤
- 21. 內存泄漏,沒有分配任何內存
- 22. 用Valgrind檢測內存泄漏
- 23. Valgrind在fclose檢測到內存泄漏()
- 24. 意外的內存泄漏[Valgrind]
- 25. 在valgrind中檢查到內存泄漏
- 26. 在strdup中Valgrind內存泄漏
- 27. 哈希表valgrind內存泄漏
- 28. Valgrind的內存泄漏/問題
- 29. C內存泄漏和Valgrind輸出
- 30. c pthreads + valgrind =內存泄漏:爲什麼?
如果您不斷向vector中添加項目,並且在執行結束時清除向量,而這些向量不會在Valgrind中顯示爲泄漏,但並不意味着它不是問題。 – paulm
當你分配一些內存時,系統分配的方式比你提出的要多,通常是頁面大小的倍數,以提高下一次內存分配的性能。由於你的程序沒有結束,系統永遠不會釋放這個內存(釋放程序中的內存只會告訴內存可以再次使用)。 – Chnossos
你究竟「重新啓動」到底如何?這是否涉及殺死它,然後再次啓動該過程? – merlin2011