【內(nei)存(cun)泄(xie)露(lu)】內(nei)存(cun)泄(xie)露(lu)是什(shen)么意(yi)思 內(nei)存(cun)泄(xie)漏的原因是什(shen)么
內存泄露是什么意思
內(nei)存泄漏(Memory Leak)是指程(cheng)(cheng)序中己動態分配的堆內存由于某種原因程(cheng)(cheng)序未釋放(fang)或無法釋放(fang),造成系統(tong)(tong)內存的浪費,導致程(cheng)(cheng)序運行速度(du)減慢(man)甚(shen)至系統(tong)(tong)崩潰等嚴重后(hou)果。 內存泄漏缺陷具有隱蔽性、積累性的特征,比其他內存非法訪問錯誤更難檢測。因為內存泄(xie)漏的(de)產(chan)生(sheng)原因是(shi)內存(cun)塊(kuai)未被釋放,屬于遺漏型(xing)缺陷(xian)而(er)不(bu)是(shi)過錯(cuo)型(xing)缺陷(xian)。此外,內存(cun)泄(xie)漏通常不(bu)會(hui)直接(jie)產(chan)生(sheng)可觀察(cha)的(de)錯(cuo)誤癥狀,而(er)是(shi)逐漸(jian)積累(lei),降低系統整(zheng)體性能(neng),極端的(de)情況下可能(neng)使系統崩潰(kui)。 隨著計算機應用需求的日益增加,應用程序的設計與開發也相應的日趨復雜,開發人員在程序實現的過程中處理的變量也大量增加,如何有效進行內存分配和釋放,防止內存泄漏的問題變得越來越突出。例如服務器應用軟件,需要長時間的運行,不斷的處理由客戶端發來的請求,如果沒有有效的內存管理,每處理一次請求信息就有一定的內存泄漏。這樣不僅影響到服務器的性能,還可能造成整個系統的崩潰。因此,內存管理成為軟件設計開發人員在設計中考慮的主要方面。
內存泄漏的原因是什么
在C語言中(zhong),從變(bian)(bian)量(liang)(liang)存(cun)(cun)在(zai)的時間(jian)(jian)生(sheng)命(ming)周期角度上,把變(bian)(bian)量(liang)(liang)分(fen)為靜(jing)態(tai)存(cun)(cun)儲(chu)(chu)變(bian)(bian)量(liang)(liang)和(he)動態(tai)存(cun)(cun)儲(chu)(chu)變(bian)(bian)量(liang)(liang)兩(liang)類(lei)。靜(jing)態(tai)存(cun)(cun)儲(chu)(chu)變(bian)(bian)量(liang)(liang)是指在(zai)程(cheng)序運行期間(jian)(jian)分(fen)配了(le)固定(ding)存(cun)(cun)儲(chu)(chu)空(kong)間(jian)(jian)的變(bian)(bian)量(liang)(liang)而動態(tai)存(cun)(cun)儲(chu)(chu)變(bian)(bian)量(liang)(liang)是指在(zai)程(cheng)序運行期間(jian)(jian)根(gen)據實際需要進行動態(tai)地分(fen)配存(cun)(cun)儲(chu)(chu)空(kong)間(jian)(jian)的變(bian)(bian)量(liang)(liang)。在(zai)內存(cun)(cun)中(zhong)供用(yong)戶使用(yong)的內存(cun)(cun)空(kong)間(jian)(jian)分(fen)為三部分(fen): 程序存儲區 靜態存儲區 動態存儲區 程(cheng)(cheng)(cheng)(cheng)序(xu)中(zhong)所用的(de)(de)數據分(fen)別存(cun)(cun)放在(zai)靜態(tai)存(cun)(cun)儲區和(he)(he)動(dong)(dong)(dong)態(tai)存(cun)(cun)儲區中(zhong)。靜態(tai)存(cun)(cun)儲區數據在(zai)程(cheng)(cheng)(cheng)(cheng)序(xu)的(de)(de)開始(shi)就(jiu)分(fen)配(pei)好內存(cun)(cun)區,在(zai)整個程(cheng)(cheng)(cheng)(cheng)序(xu)執(zhi)行過程(cheng)(cheng)(cheng)(cheng)中(zhong)它(ta)們所占的(de)(de)存(cun)(cun)儲單(dan)元是(shi)固定的(de)(de),在(zai)程(cheng)(cheng)(cheng)(cheng)序(xu)結束時就(jiu)釋(shi)(shi)放,因此(ci)靜態(tai)存(cun)(cun)儲區數據一般(ban)為全(quan)局變(bian)(bian)量(liang)(liang)。動(dong)(dong)(dong)態(tai)存(cun)(cun)儲區數據則是(shi)在(zai)程(cheng)(cheng)(cheng)(cheng)序(xu)執(zhi)行過程(cheng)(cheng)(cheng)(cheng)中(zhong)根據需要動(dong)(dong)(dong)態(tai)分(fen)配(pei)和(he)(he)動(dong)(dong)(dong)態(tai)釋(shi)(shi)放的(de)(de)存(cun)(cun)儲單(dan)元,動(dong)(dong)(dong)態(tai)存(cun)(cun)儲區數據有三類(lei)函(han)數形參(can)變(bian)(bian)量(liang)(liang)、局部變(bian)(bian)量(liang)(liang)和(he)(he)函(han)數調用時的(de)(de)現(xian)場保護與(yu)返回(hui)地址。由于(yu)動(dong)(dong)(dong)態(tai)存(cun)(cun)儲變(bian)(bian)量(liang)(liang)可以根據函(han)數調用的(de)(de)需要,動(dong)(dong)(dong)態(tai)地分(fen)配(pei)和(he)(he)釋(shi)(shi)放存(cun)(cun)儲空間,大大提高了內存(cun)(cun)的(de)(de)使(shi)用效率(lv),使(shi)得動(dong)(dong)(dong)態(tai)存(cun)(cun)儲變(bian)(bian)量(liang)(liang)在(zai)程(cheng)(cheng)(cheng)(cheng)序(xu)中(zhong)被廣(guang)泛使(shi)用。 開發(fa)人(ren)員進行(xing)程序(xu)開發(fa)的過程使用(yong)動態(tai)存(cun)(cun)儲變量(liang)時(shi),不可避免地面對(dui)內(nei)存(cun)(cun)管理的問(wen)題。程序(xu)中動態(tai)分配(pei)(pei)的存(cun)(cun)儲空(kong)(kong)間,在(zai)程序(xu)執(zhi)行(xing)完畢后需要進行(xing)釋放。沒有釋放動態(tai)分配(pei)(pei)的存(cun)(cun)儲空(kong)(kong)間而造成內(nei)存(cun)(cun)泄漏,是使用(yong)動態(tai)存(cun)(cun)儲變量(liang)的主要問(wen)題。一般情況下,開發(fa)人(ren)員使用(yong)系(xi)統提供的內(nei)存(cun)(cun)管理基本函數,如(ru)malloc、recalloc、calloc、free等,完(wan)成動(dong)態存(cun)(cun)儲變量存(cun)(cun)儲空間(jian)的(de)分配和釋放。但(dan)是(shi),當開發程序(xu)中使用(yong)動(dong)態存(cun)(cun)儲變量較多和頻繁(fan)使用(yong)函數調(diao)用(yong)時,就會(hui)經常發生內存(cun)(cun)管理錯誤,例如: 分配一個內(nei)存塊并使(shi)用其中未(wei)經初(chu)始化的(de)內(nei)容; 釋放一(yi)個(ge)內存塊,但繼續引用其中的內容; 子函(han)數(shu)(shu)(shu)中(zhong)分(fen)配(pei)(pei)的內(nei)存空間在主函(han)數(shu)(shu)(shu)出現異常中(zhong)斷時、或主函(han)數(shu)(shu)(shu)對子函(han)數(shu)(shu)(shu)返回的信息使用結束時,沒有對分(fen)配(pei)(pei)的內(nei)存進行釋放; 程(cheng)序實現過(guo)程(cheng)中分配的臨(lin)時(shi)內存在程(cheng)序結束時(shi),沒有釋放臨(lin)時(shi)內存。內存錯誤一般是不可再(zai)現的,開發(fa)人員(yuan)不易在程(cheng)序調試(shi)(shi)和測試(shi)(shi)階段(duan)發(fa)現,即使花(hua)費了很多精(jing)力和時(shi)間(jian),也無法(fa)徹底消除。 產生方式的分類 以產(chan)生的方式來分類,內存泄漏可以分為四類: 1、常發性內存泄漏 發生內(nei)存(cun)泄漏的代(dai)碼(ma)會被(bei)多次執(zhi)行到(dao),每(mei)次被(bei)執(zhi)行時都會導(dao)致一塊內(nei)存(cun)泄漏。 2、偶發性內存泄漏 發(fa)生內存(cun)泄漏的(de)代(dai)碼只有在某些(xie)特(te)定(ding)環(huan)境或操(cao)作過程下才會發(fa)生。常(chang)發(fa)性和偶(ou)發(fa)性是相對(dui)(dui)(dui)的(de)。對(dui)(dui)(dui)于特(te)定(ding)的(de)環(huan)境,偶(ou)發(fa)性的(de)也許就變成了常(chang)發(fa)性的(de)。所以(yi)測試環(huan)境和測試方法對(dui)(dui)(dui)檢(jian)測內存(cun)泄漏至關重要(yao)。 3、一次性內存泄漏 發生(sheng)內存(cun)泄(xie)漏的(de)代碼只會被執行一(yi)次,或者由(you)于算法上(shang)的(de)缺陷,導致總會有一(yi)塊且僅有一(yi)塊內存(cun)發生(sheng)泄(xie)漏。 4、隱式內存泄漏 程序在運行過程中不停的分配內存,但是直到結束的時候才釋放內存。嚴格的說這里并沒有發生內存泄漏,因為最終程序釋放了所有申請的內存。但是對于一個服務器程序,需要運行幾天,幾周甚至幾個月,不及時釋放內存也可能導致最終耗盡系統的所有內存。所以,我們稱這類內存泄漏為隱式內存泄漏。從用戶使用程序的角度來看,內存泄漏本身不會產生什么危害,作為一般的用戶,根本感覺不到內存泄漏的存在。真正有危害的是內存泄漏的堆積,這會最終耗盡系統所有的內存。從這個角度來說,一次性內存泄漏并沒有什么危害,因為它不會堆積,而隱式內存泄漏危害性則非常大,因為較之于常發性和偶發性內存泄漏它更難被檢測到。