什么是內存泄漏?什么是內存溢出?


有時候會有人問你, 內存泄漏是什么? 什么原因導致的? 如何解決?

那么內存溢出又是什么呢?

 

一一的解釋一下:

 

內存溢出 out of memory: 是指程序員在申請內存時,沒有足夠的內存空間供其實用。比如 你申請了 2kb 的內存空間。 但是給了一個需要4kb才能存下的數據。 這就是內存溢出了。內存溢出就是, 你要求分配的內存超出了系統能夠給你的內存。從而系統不能夠滿足需求,於是產生了溢出。

一個盤子只能裝4個蘋果,但是你硬是裝了5個,結果掉地上了不能吃了。這就是內存溢出! 比如說棧,棧滿時在做進棧的操作必定產生空間溢出,這叫做上溢,棧空時再做出棧的操作也會產生空間溢出,這叫做下溢。 就是分配的內存不足以放下數據項序列,成為內存溢出。

 

內存泄漏 mempry leak:是指你向系統申請分配內存進行(new)。但是使用完成之后卻不歸還(delete),可是你申請到的那塊內存連你自己都不能訪問了(有可能是因為你把它搞丟了...),這個時候 系統也不能再次的將 這塊內存,分配給你需要的程序。

 

根據發生的方式來進行分類的話,內存泄漏可以分為4類:

1.常發性內存泄漏:發生內存泄漏的代碼會被多次執行到,每次執行都會導致一塊內存的泄漏。

2.偶發性內存泄漏:發生內存泄漏的代碼只有在特定的環境或者操作過程下才會發生。 常發性和偶發性是相對的。 對於特定的環境,偶發性的也就編程常發性的。所以測試環境和測試方法對檢測內存泄漏至關重要。

3.一次性內存泄漏:發生內存泄漏的代碼只會被執行一次,或者由於算法上的缺陷,導致總會有一塊且僅有一塊內存發生泄漏。比如在類的構建函數中分配內存,在析構函數中卻沒有釋放該內存,所以內存泄漏只會發生一次。

4.隱士內存泄漏:程序運行過程中不停的分配內存,直到程序結束才能夠釋放內存。嚴格的說這並沒有發生內存泄漏,因為程序最終釋放了所申請的內存。但是對於一個服務器程序,可能需要運行 幾天,幾周,幾月,甚至幾年。如果不及時的釋放內存,系統的內存資源最終都會被消耗完。so我們稱這種的為隱士的內存泄漏。

 

對於用戶來說內存泄漏沒什么影響,因為他們並不在乎。而且一般的用戶根本也感受不到這個東西。真正有害的是內存泄漏的堆積,因為這最終會消耗盡所有的系統資源。  從這個角度來說的話,一次性內存泄漏,其實並沒有什么危害,因為他不會大量的堆積。而隱式內存泄漏則危害最大。因為較之於常發性或偶發性的內存泄漏。他更加的難以被發現。

 

內存泄漏 mempry leak  最終會導致 內存溢出 out of memory

 

內存溢出的原因以及解決方式:

1.內存中加載的數據量,過於的龐大。 比如 一次性從數據庫取出50G數據。(吹牛逼 瞬間就爆炸了)

2.集合類中有對 對象的醫用,使用完畢后未清空。似的解釋器或編譯器 不能回收。

3.代碼中存在過多的 循環。 或者循環產生大量的重復的 實例化對象。

4.使用的第三方軟件中 存在  BUG

5.啟動參數的值設定的太小

 

內存溢出的解決方案:

1. 檢查錯誤日志,查看"OutOfMemory"錯誤千是否有其他異常或錯誤。

2.對代碼進行走查和分析,找出可能發生內存溢出的位置。

重點排查:

  1. 檢查對數據庫查詢中,是否有一次對數據庫全部數據獲取的查詢。一般來說如果一次性取出10萬記錄到內存,就會有可能產生內存溢出。這個問題比較隱蔽。在上線之前數據會比較少,不容易出問題,上線之后數據庫中數據多了。 一次查詢就有可能引起內存的溢出。因此對於數據庫的查詢盡量采取用分頁的方式。

  2.  檢查代碼中是否有死循環或遞歸調用。(遞歸的層數,不要太深)

  3. 檢查是否有大量循環重復產生新對象實例。

  4. 檢查 容器類對象是否使用完畢后,沒有被清除。(py程序員, 幾乎不需要考慮。垃圾回收機制幫你解決了)

3. 使用內存查看工具動態的查看內存的使用狀態。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM