有時候會有人問你碟案, 內(nèi)存泄漏是什么芬探? 什么原因?qū)е碌模?如何解決勇垛?
那么內(nèi)存溢出又是什么呢祟蚀?
內(nèi)存溢出 out of memory: 是指程序員在申請內(nèi)存時敬锐,沒有足夠的內(nèi)存空間供其實用衡蚂。比如 你申請了 2kb 的內(nèi)存空間粱檀。 但是給了一個需要4kb才能存下的數(shù)據(jù)仪媒。 這就是內(nèi)存溢出了姜钳。內(nèi)存溢出就是缤弦, 你要求分配的內(nèi)存超出了系統(tǒng)能夠給你的內(nèi)存领迈。從而系統(tǒng)不能夠滿足需求,于是產(chǎn)生了溢出。
一個盤子只能裝4個蘋果狸捅,但是你硬是裝了5個衷蜓,結(jié)果掉地上了不能吃了。這就是內(nèi)存溢出尘喝! 比如說棧磁浇,棧滿時在做進棧的操作必定產(chǎn)生空間溢出,這叫做上溢朽褪,椫孟牛空時再做出棧的操作也會產(chǎn)生空間溢出,這叫做下溢缔赠。 就是分配的內(nèi)存不足以放下數(shù)據(jù)項序列衍锚,成為內(nèi)存溢出。
內(nèi)存泄漏 mempry leak:是指你向系統(tǒng)申請分配內(nèi)存進行(new)嗤堰。但是使用完成之后卻不歸還(delete)戴质,可是你申請到的那塊內(nèi)存連你自己都不能訪問了(有可能是因為你把它搞丟了...),這個時候 系統(tǒng)也不能再次的將 這塊內(nèi)存踢匣,分配給你需要的程序告匠。
根據(jù)發(fā)生的方式來進行分類的話,內(nèi)存泄漏可以分為4類:
1.常發(fā)性內(nèi)存泄漏:發(fā)生內(nèi)存泄漏的代碼會被多次執(zhí)行到符糊,每次執(zhí)行都會導(dǎo)致一塊內(nèi)存的泄漏凫海。
2.偶發(fā)性內(nèi)存泄漏:發(fā)生內(nèi)存泄漏的代碼只有在特定的環(huán)境或者操作過程下才會發(fā)生。 常發(fā)性和偶發(fā)性是相對的男娄。 對于特定的環(huán)境行贪,偶發(fā)性的也就編程常發(fā)性的。所以測試環(huán)境和測試方法對檢測內(nèi)存泄漏至關(guān)重要模闲。
3.一次性內(nèi)存泄漏:發(fā)生內(nèi)存泄漏的代碼只會被執(zhí)行一次建瘫,或者由于算法上的缺陷,導(dǎo)致總會有一塊且僅有一塊內(nèi)存發(fā)生泄漏尸折。比如在類的構(gòu)建函數(shù)中分配內(nèi)存啰脚,在析構(gòu)函數(shù)中卻沒有釋放該內(nèi)存,所以內(nèi)存泄漏只會發(fā)生一次实夹。
4.隱士內(nèi)存泄漏:程序運行過程中不停的分配內(nèi)存橄浓,直到程序結(jié)束才能夠釋放內(nèi)存。嚴格的說這并沒有發(fā)生內(nèi)存泄漏亮航,因為程序最終釋放了所申請的內(nèi)存荸实。但是對于一個服務(wù)器程序,可能需要運行 幾天缴淋,幾周准给,幾月泄朴,甚至幾年。如果不及時的釋放內(nèi)存露氮,系統(tǒng)的內(nèi)存資源最終都會被消耗完祖灰。so我們稱這種的為隱士的內(nèi)存泄漏。
對于用戶來說內(nèi)存泄漏沒什么影響畔规,因為他們并不在乎局扶。而且一般的用戶根本也感受不到這個東西。真正有害的是內(nèi)存泄漏的堆積油讯,因為這最終會消耗盡所有的系統(tǒng)資源详民。 從這個角度來說的話延欠,一次性內(nèi)存泄漏陌兑,其實并沒有什么危害,因為他不會大量的堆積由捎。而隱式內(nèi)存泄漏則危害最大兔综。因為較之于常發(fā)性或偶發(fā)性的內(nèi)存泄漏。他更加的難以被發(fā)現(xiàn)狞玛。
內(nèi)存泄漏 mempry leak 最終會導(dǎo)致 內(nèi)存溢出 out of memory
內(nèi)存溢出的原因以及解決方式:
1.內(nèi)存中加載的數(shù)據(jù)量软驰,過于的龐大。 比如 一次性從數(shù)據(jù)庫取出50G數(shù)據(jù)心肪。(吹牛逼 瞬間就爆炸了)
2.集合類中有對 對象的醫(yī)用锭亏,使用完畢后未清空。似的解釋器或編譯器 不能回收硬鞍。
3.代碼中存在過多的 循環(huán)慧瘤。 或者循環(huán)產(chǎn)生大量的重復(fù)的 實例化對象。
4.使用的第三方軟件中 存在 BUG
5.啟動參數(shù)的值設(shè)定的太小
內(nèi)存溢出的解決方案:
- 檢查錯誤日志固该,查看"OutOfMemory"錯誤千是否有其他異彻酰或錯誤。
2.對代碼進行走查和分析伐坏,找出可能發(fā)生內(nèi)存溢出的位置怔匣。
重點排查:
1. 檢查對數(shù)據(jù)庫查詢中,是否有一次對數(shù)據(jù)庫全部數(shù)據(jù)獲取的查詢桦沉。一般來說如果一次性取出10萬記錄到內(nèi)存每瞒,就會有可能產(chǎn)生內(nèi)存溢出。這個問題比較隱蔽纯露。在上線之前數(shù)據(jù)會比較少剿骨,不容易出問題,上線之后數(shù)據(jù)庫中數(shù)據(jù)多了苔埋。 一次查詢就有可能引起內(nèi)存的溢出懦砂。因此對于數(shù)據(jù)庫的查詢盡量采取用分頁的方式。
2. 檢查代碼中是否有死循環(huán)或遞歸調(diào)用。(遞歸的層數(shù)荞膘,不要太深)
3. 檢查是否有大量循環(huán)重復(fù)產(chǎn)生新對象實例罚随。
4. 檢查 容器類對象是否使用完畢后,沒有被清除羽资。(py程序員, 幾乎不需要考慮淘菩。垃圾回收機制幫你解決了)
- 使用內(nèi)存查看工具動態(tài)的查看內(nèi)存的使用狀態(tài)。