如何調(diào)試內(nèi)存泄漏?方法論來(lái)了
作為程序員,特別是C/C++程序員,內(nèi)存泄漏問(wèn)題是必須要邁過(guò)的一座大山,那,
- 寫代碼時(shí)如何避免內(nèi)存泄漏?
- 出現(xiàn)內(nèi)存泄漏后,如何調(diào)試?
直奔主題!
01內(nèi)存如何避免內(nèi)存泄漏?
誰(shuí)也不能永遠(yuǎn)保證自己的代碼沒(méi)有內(nèi)存泄漏,這里我只能給出幾點(diǎn)建議:
- 充分利用RAII:考慮使用智能指針,關(guān)于智能指針是否應(yīng)用使用,相信有人聽身邊的大佬說(shuō)過(guò)不建議使用使用智能指針,可能是個(gè)帶刺的玫瑰?不過(guò)在我短暫的C++開發(fā)生涯里,我還沒(méi)有被智能指針坑過(guò),而且用起來(lái)還特別方便,因?yàn)樗娴哪軌蚪档统霈F(xiàn)內(nèi)存泄漏的概率。至于那些大佬們的不同聲音,我更傾向于Bjarne Stroustrup和Scott Meyers這些大佬們的意見,他們都建議使用智能指針,那我等小輩跟隨就完事了。
- 誰(shuí)申請(qǐng)誰(shuí)釋放:如果沒(méi)有使用智能指針,或者有些情況下沒(méi)辦法使用智能指針,那我們最好遵循一個(gè)原則,即誰(shuí)申請(qǐng)誰(shuí)釋放原則。A這里申請(qǐng)的內(nèi)存盡量在A這里釋放,不要A申請(qǐng)內(nèi)存,然后跑到B里釋放,這種代碼不直觀,一不利于排查問(wèn)題,二很容易稍微一點(diǎn)疏忽就導(dǎo)致內(nèi)存泄漏。
- 確保配對(duì)使用:new/delete,new[]/delete[]一定要配對(duì)使用,不配對(duì)使用大概率會(huì)出問(wèn)題。這里推薦看下new[]和delete[]一定要配對(duì)使用嗎?
- 小空間優(yōu)先使用棧內(nèi)存:一般內(nèi)存泄漏都是指堆內(nèi)存泄漏,我們不申請(qǐng)堆內(nèi)存,它自然就不會(huì)泄漏。
附加:這里還有個(gè)有效避免內(nèi)存泄漏的方案,就是手?jǐn)]一個(gè)內(nèi)存泄漏檢測(cè)器,在Debug模式下可以考慮開啟它,程序運(yùn)行一遍后,如果有內(nèi)存泄漏,會(huì)精確指出是在哪里出現(xiàn)的泄漏。關(guān)于內(nèi)存泄漏檢測(cè)器可以移步到這里:我擼了個(gè)內(nèi)存泄漏檢測(cè)工具,只用了兩招,其實(shí)原理就是重載operator new和operator delete。
02如何調(diào)試內(nèi)存泄漏?
既然是調(diào)試,那就得用上工具,調(diào)試內(nèi)存泄漏的工具有很多,最經(jīng)典的就是valgrind和Asan,valgrind非常好用,但是在移動(dòng)端不太好用,特別是Android,移植起來(lái)非常困難,而且還要sudo權(quán)限。而Asan就好多了,在哪里都能用,關(guān)于Asan我之前寫文章介紹過(guò),可以看這里:Linux如何調(diào)試內(nèi)存泄漏。
然而如果是在移動(dòng)端,我還發(fā)現(xiàn)了一個(gè)好用的開源庫(kù):https://github.com/tencent/matrix
這是一個(gè)騰訊出品的性能剖析工具,適用于Android和iOS,內(nèi)存泄漏檢測(cè)只是功能之一,更多功能大家可以自己去看看,確實(shí)不錯(cuò)。
打完收工。