隱性的內存泄露問題
內存泄漏(Memory Leak)是指程序中已動態分配的堆內存由于某種原因程序未釋放或無法釋放,造成系統內存的浪費,導致程序運行速度減慢甚至系統崩潰等嚴重后果。內存泄露是一個嚴重的慢性病,不會立即展現,但不知道未來的哪一天,所有的設備,會在相近的時間點爆發問題。
內存泄漏還會導致系統意外的重啟,重啟的原因可能千奇百怪。因此,檢測和解決內存泄漏,就顯得非常重要。
1. 泄漏的原因
內存泄漏主要是發生在堆內存分配方式中,即malloc方式中,申請的內存沒有得到釋放,或者對應的指針被被覆蓋,內存直接泄漏。因為內存泄漏屬于程序運行中的問題,無法通過編譯識別,主要在程序運行過程中來判別和診斷。
2. 動態檢測或監控是否內存泄露
監控系統內存,周期性監控堆中可用內存的大小,是檢測系統是否有內存泄漏的最有效的手段。系統的內存短期會隨著業務數據的變化而變化,但長期來看,可用的剩余可用內存會圍繞一個中軸線上下波動,如果存在內存泄漏,其剩余可用內存隨隨著時間的推移逐漸減少。
3. 如何找到在哪兒內存泄露
可以使用工具檢測代碼中有沒有靜態的內存泄露,也可以在代碼中增加標記,檢測長期未釋放的堆是誰申請的,在代碼中查找。可以參考文章《動態內存管理及防御性編程》。
指針跑飛的問題
指針跑飛就是指針指向不正確的位置,指針未初始化或數組/指針越界訪問,導致系統崩潰。
指針跑飛是常見的問題,問題很嚴重,但解決起來其實并不難,指針跑飛系統crash時,如果平臺軟件會打印出函數調用棧、segment fault錯誤、代碼出錯的地方、coredump文件等信息。有了這些信息,再分析源代碼,其實是很容發現或找出當前代碼中指針跑飛的原因的。
如果基于第三方的SDK開發,指針跑飛直接就重啟,可能不會有任何提示,因此,最好能夠在編碼時就能夠提前預防,而不是等待程序跑飛之后再定位解決 。
常見的手段:
1、熟悉和遵守代碼編寫規范,加強代碼的評審,把問題消滅在編碼階段。
2、靜態檢測工具對代碼進行檢測。
3、增加邊界性測試用例,一般指針異常是在邊界或異常情形下發生的。
4、增加異常場景的測試,異常場景是違反常規的測試場景,這些異常業務場景,能夠盡早shi發現隱藏的問題。
空指針的問題
空指針是“指針跑飛”的一種特殊情況,即指針為NULL,通常出現在指針用NULL值初始化后,在某些情況下沒有給指針賦值,就直接使用指針范圍內存。或者接收函數返回的指針變量,忽略了函數返回NULL的情形。
在使用指針前,檢查指針是否為空,如果為空,在代碼中執行異常處理流程,如打印出錯信息,或者ASSERT,這樣就可以避免引起更嚴重的問題,相對來說多使用一個if即可規避。
棧溢出導致的問題
棧溢出時會訪問不存在的RAM空間,造成代碼跑飛,這時無法得到溢出時的上下文數據,也無法對后續的程序修改提供有用信息。
函數遞歸調用,系統要在棧中不斷保存函數調用時的現場和產生的變量,如果遞歸調用太深,就會造成棧溢出。函數內局部數組變量的內存空間過大,或者局部數組變量的下標范圍溢出,破壞了棧空間中的內容。這種問題容易解決但初始不容易查到原因。如果是帶操作系統的,一般系統內核會直接提示棧空間不足,將任務棧空間加大,或者不靜態分配,用malloc動態創建,從堆中分配的。平時編碼中禁止使用循環遞歸函數。
-
內存
+關注
關注
8文章
3028瀏覽量
74096 -
嵌入式軟件
+關注
關注
4文章
240瀏覽量
26653 -
檢測工具
+關注
關注
0文章
21瀏覽量
2024
發布評論請先 登錄
相關推薦
評論