乙個很難發現的記憶體洩漏

2022-09-18 20:15:14 字數 1320 閱讀 7103

當你的資源釋放以後,再去訪問時,就會出現各種錯誤,比如物件返回空,資源不存在等等,這些錯誤都是編譯的時候語法合理的,但是一旦執行到了這裡,肯定就會出錯了(這一塊如果沒被執行的話,還是發現不了錯誤的)。而且很難找到這個錯誤的原因(不在於這個錯誤有多麼的難,而是**太多,關係太複雜,沒有很好地條理去分析,邏輯混亂了以後,就會覺得太可怕了)。因此,找bug需要時刻保持清醒的頭腦,這個bug我昨天從下午到晚上十點多,一直找都沒解出來,今天上午剛起床,來到自習室,冷靜的分析了片刻,很快就看出來了問題的癥結。

設想一下如果申請的堆記憶體不夠我放下想要的資料,但是我確實又把所有想要的資料都放入了其中,會發生什麼???

這是乙個特別奇葩的記憶體洩漏,我之前根本就沒想過粗心會導致這種錯誤!!!

當你(new)申請的堆空間只夠放下乙個物件時(如上圖),實際上你卻可以用這個指標陣列存放不止乙個物件,當你存放了2個及以上物件時(也就是超過了申請的堆記憶體空間),這個時候,編譯合法,執行也正常(這點很奇怪,但是這是事實),不過當你的程式退出時,會呼叫析構函式,如果你在析構函式中手動的釋放這塊記憶體的話,就會出現記憶體洩漏了!!!!!!!!!!

原因:因為原來只分配了乙個物件的記憶體空間,但是你卻向這塊記憶體中放了不止乙個物件(這樣做 語法正確,執行也正確),因此delete這個指標的時候,只會釋放乙個記憶體的空間,因此導致了其餘物件的記憶體空間沒有釋放,出現了記憶體洩漏被其他程式檢測到(可能是核心又或者是相關的支援程式亦或是程式本身有監測機制),就會提示錯誤了。

關於new申請記憶體的個人看法:

如上所述,關於 「申請的堆空間只夠放下乙個物件時(如上圖),實際上你卻可以用這個指標陣列存放不止乙個物件」 為什麼能夠成功的正常執行。

首先來反推一下,程式能夠正常的執行(只是在退出的時候呼叫一些析構函式釋放記憶體空間出錯)說明我實實在在的使用了少量申請到的記憶體存放了

超過這個記憶體塊大小的資料,並且這些資料是能夠被正常訪問到的,也就是說這塊記憶體區域對應用程式來說是合法的(否則會報錯「記憶體訪問衝突」),

儘管設計者並沒有申請這麼多的記憶體。

再聯想一下裝置的這些硬體資源全部都由核心管理以及分配給應用程式,並且這些由核心管理的記憶體空間是以最小單位頁被分配給應用程式的,所以

申請乙個物件的空間的時候,核心會以頁為單位分配記憶體空間給應用程式,所以就會出現  「申請的堆空間只夠放下乙個物件時(如上圖),實際上你卻

可以用這個指標陣列存放不止乙個物件」  的情況了!!!

乙個記憶體洩漏問題的排查

監控的mem一直居高不下 使用jstat命令檢視gc的情況,發現ygc已經停止,一直在fgc,懷疑記憶體已經洩漏,堆記憶體中有大量無法 的物件。然後檢視gc日誌,發現年輕代和老年代使用率達到99 且full gc後記憶體沒有被 確定肯定是有物件無法被 需要解密的資料 這是加解密的功能,每次執行加解密...

分享乙個輔助分析記憶體洩漏的指令碼

最近給系統做了一點優化,前幾天去檢視系統監控,想看看上線前後cpu使用率曲線變化情況。檢視的時候意外發現上線前後記憶體占用相差不少,20 以上。本來我沒怎麼在意這個問題,因為我們系統會在執行過程中快取部分資料內容。但客戶覺得有異常,堅持要查。於是把乙個月的記憶體使用情況調出來看,這一看就發現問題了 ...

關於C 記憶體洩漏的乙個經驗教訓

近期寫了一段 發現有記憶體洩漏,經多次查詢都找不到源點,搞到焦頭爛額,最後經同事細心審查,競是粗心導致的隱藏性錯誤,為了在以後避免犯同樣的錯誤,有必有記錄下來。在c 中記憶體管理是很重要的,特別是在new 出記憶體後,一定要用到相應的delete釋放記憶體,否則就會出現記憶體洩漏。其實,一般寫 都會...