隱性的內(nèi)存泄露問(wèn)題
內(nèi)存泄漏(Memory Leak)是指程序中已動(dòng)態(tài)分配的堆內(nèi)存由于某種原因程序未釋放或無(wú)法釋放,造成系統(tǒng)內(nèi)存的浪費(fèi),導(dǎo)致程序運(yùn)行速度減慢甚至系統(tǒng)崩潰等嚴(yán)重后果。內(nèi)存泄露是一個(gè)嚴(yán)重的慢性病,不會(huì)立即展現(xiàn),但不知道未來(lái)的哪一天,所有的設(shè)備,會(huì)在相近的時(shí)間點(diǎn)爆發(fā)問(wèn)題。
內(nèi)存泄漏還會(huì)導(dǎo)致系統(tǒng)意外的重啟,重啟的原因可能千奇百怪。因此,檢測(cè)和解決內(nèi)存泄漏,就顯得非常重要。
1. 泄漏的原因
內(nèi)存泄漏主要是發(fā)生在堆內(nèi)存分配方式中,即malloc方式中,申請(qǐng)的內(nèi)存沒(méi)有得到釋放,或者對(duì)應(yīng)的指針被被覆蓋,內(nèi)存直接泄漏。因?yàn)閮?nèi)存泄漏屬于程序運(yùn)行中的問(wèn)題,無(wú)法通過(guò)編譯識(shí)別,主要在程序運(yùn)行過(guò)程中來(lái)判別和診斷。
2. 動(dòng)態(tài)檢測(cè)或監(jiān)控是否內(nèi)存泄露
監(jiān)控系統(tǒng)內(nèi)存,周期性監(jiān)控堆中可用內(nèi)存的大小,是檢測(cè)系統(tǒng)是否有內(nèi)存泄漏的最有效的手段。系統(tǒng)的內(nèi)存短期會(huì)隨著業(yè)務(wù)數(shù)據(jù)的變化而變化,但長(zhǎng)期來(lái)看,可用的剩余可用內(nèi)存會(huì)圍繞一個(gè)中軸線上下波動(dòng),如果存在內(nèi)存泄漏,其剩余可用內(nèi)存隨隨著時(shí)間的推移逐漸減少。
3. 如何找到在哪兒內(nèi)存泄露
可以使用工具檢測(cè)代碼中有沒(méi)有靜態(tài)的內(nèi)存泄露,也可以在代碼中增加標(biāo)記,檢測(cè)長(zhǎng)期未釋放的堆是誰(shuí)申請(qǐng)的,在代碼中查找??梢詤⒖嘉恼隆秳?dòng)態(tài)內(nèi)存管理及防御性編程》。
指針跑飛的問(wèn)題
指針跑飛就是指針指向不正確的位置,指針未初始化或數(shù)組/指針越界訪問(wèn),導(dǎo)致系統(tǒng)崩潰。
指針跑飛是常見(jiàn)的問(wèn)題,問(wèn)題很?chē)?yán)重,但解決起來(lái)其實(shí)并不難,指針跑飛系統(tǒng)crash時(shí),如果平臺(tái)軟件會(huì)打印出函數(shù)調(diào)用棧、segment fault錯(cuò)誤、代碼出錯(cuò)的地方、coredump文件等信息。有了這些信息,再分析源代碼,其實(shí)是很容發(fā)現(xiàn)或找出當(dāng)前代碼中指針跑飛的原因的。
如果基于第三方的SDK開(kāi)發(fā),指針跑飛直接就重啟,可能不會(huì)有任何提示,因此,最好能夠在編碼時(shí)就能夠提前預(yù)防,而不是等待程序跑飛之后再定位解決 。
常見(jiàn)的手段:
1、熟悉和遵守代碼編寫(xiě)規(guī)范,加強(qiáng)代碼的評(píng)審,把問(wèn)題消滅在編碼階段。
2、靜態(tài)檢測(cè)工具對(duì)代碼進(jìn)行檢測(cè)。
3、增加邊界性測(cè)試用例,一般指針異常是在邊界或異常情形下發(fā)生的。
4、增加異常場(chǎng)景的測(cè)試,異常場(chǎng)景是違反常規(guī)的測(cè)試場(chǎng)景,這些異常業(yè)務(wù)場(chǎng)景,能夠盡早shi發(fā)現(xiàn)隱藏的問(wèn)題。
空指針的問(wèn)題
空指針是“指針跑飛”的一種特殊情況,即指針為NULL,通常出現(xiàn)在指針用NULL值初始化后,在某些情況下沒(méi)有給指針賦值,就直接使用指針?lè)秶鷥?nèi)存?;蛘呓邮蘸瘮?shù)返回的指針變量,忽略了函數(shù)返回NULL的情形。
在使用指針前,檢查指針是否為空,如果為空,在代碼中執(zhí)行異常處理流程,如打印出錯(cuò)信息,或者ASSERT,這樣就可以避免引起更嚴(yán)重的問(wèn)題,相對(duì)來(lái)說(shuō)多使用一個(gè)if即可規(guī)避。
棧溢出導(dǎo)致的問(wèn)題
棧溢出時(shí)會(huì)訪問(wèn)不存在的RAM空間,造成代碼跑飛,這時(shí)無(wú)法得到溢出時(shí)的上下文數(shù)據(jù),也無(wú)法對(duì)后續(xù)的程序修改提供有用信息。
函數(shù)遞歸調(diào)用,系統(tǒng)要在棧中不斷保存函數(shù)調(diào)用時(shí)的現(xiàn)場(chǎng)和產(chǎn)生的變量,如果遞歸調(diào)用太深,就會(huì)造成棧溢出。函數(shù)內(nèi)局部數(shù)組變量的內(nèi)存空間過(guò)大,或者局部數(shù)組變量的下標(biāo)范圍溢出,破壞了??臻g中的內(nèi)容。這種問(wèn)題容易解決但初始不容易查到原因。如果是帶操作系統(tǒng)的,一般系統(tǒng)內(nèi)核會(huì)直接提示??臻g不足,將任務(wù)棧空間加大,或者不靜態(tài)分配,用malloc動(dòng)態(tài)創(chuàng)建,從堆中分配的。平時(shí)編碼中禁止使用循環(huán)遞歸函數(shù)。
-
內(nèi)存
+關(guān)注
關(guān)注
8文章
3159瀏覽量
75976 -
嵌入式軟件
+關(guān)注
關(guān)注
4文章
246瀏覽量
27764 -
檢測(cè)工具
+關(guān)注
關(guān)注
0文章
22瀏覽量
2179
發(fā)布評(píng)論請(qǐng)先 登錄
嵌入式軟件工程師的內(nèi)功修煉
嵌入式軟件測(cè)試的秘訣
嵌入式軟件是如何運(yùn)行的?
嵌入式系統(tǒng)內(nèi)存優(yōu)化使用
分享一些嵌入式系統(tǒng)編程中內(nèi)存操作相關(guān)的避坑指南
嵌入式指針的相關(guān)資料分享
使用后嵌入式指針的方法
嵌入式Web訪問(wèn)時(shí)的內(nèi)存丟失問(wèn)題
嵌入式軟件的開(kāi)發(fā)流程_嵌入式軟件的調(diào)試
嵌入式系統(tǒng)的內(nèi)存指針操作
嵌入式軟件測(cè)試總結(jié)
【嵌入式技能樹(shù)】
嵌入式軟件概述及相關(guān)測(cè)試特點(diǎn)

嵌入式軟件內(nèi)存與指針相關(guān)問(wèn)題
評(píng)論