有時候會有人問你, 內存泄漏是什么? 什么原因導致的? 如何解決?
那么內存溢出又是什么呢?
一一的解釋一下:
內存溢出 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. 使用內存查看工具動態的查看內存的使用狀態。
