C語言 主函數退出前,還佔用了大量的內存,是什麼原因造成的呢?

valgrind 檢測沒有內存泄露!

沒有靜態變數分配內存

方法是在return函數之前,加入sleep函數,休眠60秒。使用top查看進程內存大小消耗(RES800M)。

top結果如下:

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND

5301 rs 20 0 2289m 811m 1228 S 0.0 2.0 76:10.22 cg


因為C語言在main函數之間做過很多動作,main函數返回也不意味著代碼立即結束執行。

main函數也是被其它函數調用的,不然你以為argc和argv是誰初始化的?還不是C本身把命令行參數處理才得到的。main函數之前有大量的初始化工作要做,main函數沒malloc不代表初始化的時候沒有人去malloc。

下圖就是VC在main函數之前的調用棧:

另外,對於C語言的實現來說,malloc完再free,內存不是馬上返回給操作系統的。


北極沒說到點子上。

其實這裡的問題不一定是因為main之前和之後的調用。

原因主要是兩個

1,全局的對象。全局的對象在main初始化之前初始化,在main之後銷毀。所以這些內存還沒釋放。

2,操作系統內存優化機制。如果沒有全局對象你也會發現內存不會及時釋放。這是操作系統的內存優化機制決定的。只要你內存空間不是很緊張,系統會為你保存你剛才申請過的內存空間大小以便於你待會再次申請使用。這一直會持續到進程退出,或者你長時間不重新申請而其他進程需要更多內存,那就會從原先替你保留的內存中把空閑挪過去用。

第二點容易被人忽視,而且主要是在linux系統比較顯著,你試試在windows上測試類似代碼,在return之前大部分都會釋放掉了。


由於linux內存管理和glibc內存管理,導致了這種疑似內存泄漏的問題!

想了解其中機制,可以看看下面的網址:

linux下進程內存疑似泄漏分析小朱博客

十問 Linux 虛擬內存管理 (glibc)

同時,了解一下tcmalloc和jemalloc分配機制。

最後謝謝前面幫忙解答的人!


有用malloc分配內存?


推薦閱讀:

vc++6.0是不是很多優點?如何使用visual studio2013達到相同的功能?
為什麼 C 語言中的一些特性不被 C++ 支持?
C 語言有沒有REPL啊?
如何評價《王垠:C 編譯器優化過程中的 Bug》?

TAG:C編程語言 | CC | 內存泄露 |