日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無先后,達者為師

網(wǎng)站首頁 編程語言 正文

關(guān)于C++解決內(nèi)存泄漏問題的心得

作者:夢回兵工廠 更新時間: 2022-11-14 編程語言

目錄

      • 一、羅列項目中出現(xiàn)內(nèi)存泄漏的地方
        • 1.1 new delete
          • (1)異常場景分支忘記釋放
          • (2)new type[] 與delete[]
        • 1.2 打開的文件未關(guān)閉
        • 1.3 打開的磁盤路徑?jīng)]有關(guān)閉
        • 14 調(diào)用的第三方接口,內(nèi)部申請了內(nèi)存,但是沒有釋放
        • 1.5 全局變量只往里塞數(shù)據(jù),但是沒有及時清理
      • 二、導(dǎo)致內(nèi)存泄漏很難定位解決的原因
        • 2.1 工程技術(shù)鏈路長,模塊多
        • 2.2 很多代碼不熟悉
        • 2.3 很難復(fù)現(xiàn)
        • 2.4 個人能力菜
      • 三、總結(jié)內(nèi)存泄漏問題的解決流程
        • 3. 1 使用內(nèi)存泄漏定位工具,先篩查一遍
        • 3.2 手動搜索new/delete、malloc/free
        • 3.3 代碼分塊注釋與測試

最近做的項目,頻頻出現(xiàn)內(nèi)存泄漏問題,感覺就像是老頭疼,剛治好了這,那又犯了。
以下僅是對個人項目里的內(nèi)存泄漏問題做個記錄總結(jié),并非系統(tǒng)性技術(shù)分享。

一、羅列項目中出現(xiàn)內(nèi)存泄漏的地方

1.1 new delete

基本上只要new出來的內(nèi)存,都已經(jīng)delete掉了。但是還是出現(xiàn)了以下問題:

(1)異常場景分支忘記釋放

但是還是有遺漏的:在一些小概率的異常場景分支,直接return結(jié)束了函數(shù),但是忘記了delete掉函數(shù)內(nèi)申請的內(nèi)存。

(2)new type[] 與delete[]

申請內(nèi)存時,是以new type[] 形式申請的內(nèi)存,釋放時需要使用delete[]才能釋放徹底。

1.2 打開的文件未關(guān)閉

使用fstream讀磁盤文件的時候,只打開了文件流,但是沒有使用.close()函數(shù)關(guān)閉。

1.3 打開的磁盤路徑?jīng)]有關(guān)閉

使用opendir()打開文件夾路徑,但是沒有用closedir()函數(shù)關(guān)閉

14 調(diào)用的第三方接口,內(nèi)部申請了內(nèi)存,但是沒有釋放

有的第三方接口,內(nèi)部申請了內(nèi)存等資源,但是不會自動回收,所以還需要調(diào)用其對應(yīng)的資源釋放接口。如tensorRT的creatInferRuntime()、deserializeCudaEngine()、createExecutionContext()等接口,需要使用destroy()函數(shù)將其銷毀;

1.5 全局變量只往里塞數(shù)據(jù),但是沒有及時清理

一些存放數(shù)據(jù)的全局變量,例如我項目里的目標特征庫,雖然已經(jīng)有了一些邏輯會根據(jù)不同業(yè)務(wù)場景清理數(shù)據(jù)縮減其規(guī)模,但是還是建議,直接有一個暴力的條件判斷以防不測:定期判斷全局變量的容量大小,當容量超過某特別大的閾值時,暴力縮減存儲的數(shù)據(jù)甚至清空。

二、導(dǎo)致內(nèi)存泄漏很難定位解決的原因

2.1 工程技術(shù)鏈路長,模塊多

沒辦法,不過代碼能分成模塊也挺好,至少做代碼注釋定位問題時很方便。

2.2 很多代碼不熟悉

集成的多個代碼模塊,都是網(wǎng)上下載的開源代碼,對其中邏輯不熟悉。
以后找資源的時候,盡可能找一些靠譜的。

2.3 很難復(fù)現(xiàn)

這一點很重要,能成功復(fù)現(xiàn)出問題,基本上就解決一半問題了。
有的內(nèi)存泄漏不是必現(xiàn),可能是某個小概率條件分支里有泄漏。

2.4 個人能力菜

三、總結(jié)內(nèi)存泄漏問題的解決流程

3. 1 使用內(nèi)存泄漏定位工具,先篩查一遍

工程如果比較大,直接剛代碼肯定是不明智的。
注意工具不是萬能的,但是能查出來一處泄漏,也是有幫助的。
內(nèi)存泄漏定位工具(linux):valgrind、asan(AddressSanitizer)、Sonarqube、vscode-cppcheck插件等;
內(nèi)存監(jiān)測工具(linux):top、Telegraf+Influxdb+Grafana三件套
內(nèi)存泄漏工具windows:VS2015性能探測器、VLD嵌入式分析、windbg工具udmh解決定位內(nèi)存泄漏方法、LeakDiag內(nèi)存泄漏分析LDGrapher查看

3.2 手動搜索new/delete、malloc/free

new與delete、malloc與free都要成對使用,注意異常場景下別忘記釋放(每個分支都要閉環(huán))。

3.3 代碼分塊注釋與測試

看上去最低效,但是個人感覺是最有效的,尤其是上面方法都用完以后還是有泄漏,但是兜兜轉(zhuǎn)轉(zhuǎn),還是祭出了本大招。
逐塊注釋代碼,然后運行看是否有泄漏,不斷縮小可疑代碼的范圍。

最后:代碼虐我千萬遍,都是淚啊。。。

原文鏈接:https://blog.csdn.net/m0_37635769/article/details/127836661

欄目分類
最近更新