學習啦 > 學習電腦 > 電腦故障 > 內存故障 > 內存溢出的原因有哪些?怎么解決?

內存溢出的原因有哪些?怎么解決?

時間: 伯超1226 分享

內存溢出的原因有哪些?怎么解決?

  內存溢出 out of memory,是指程序在申請內存時,沒有足夠的內存空間供其使用,出現(xiàn)out of memory;比如申請了一個integer,但給它存了long才能存下的數(shù),那就是內存溢出。那么當你遇到這種情況時該怎么辦呢?今天小編為大家整理了一些解決方法,下面我們一起來看看吧!

  簡介

  內存泄漏是指你向系統(tǒng)申請分配內存進行使用(new),可是使用完了以后卻不歸還(delete),結果你申請到的那塊內存你自己也不能再訪問(也許你把它的地址給弄丟了),而系統(tǒng)也不能再次將它分配給需要的程序。一個盤子用盡各種方法只能裝4個果子,你裝了5個,結果掉倒地上不能吃了。這就是溢出!比方說棧,棧滿時再做進棧必定產生空間溢出,叫上溢,??諘r再做退棧也產生空間溢出,稱為下溢。就是分配的內存不足以放下數(shù)據項序列,稱為內存溢出.

  以發(fā)生的方式來分類,內存泄漏可以分為4類:

  1. 常發(fā)性內存泄漏。發(fā)生內存泄漏的代碼會被多次執(zhí)行到,每次被執(zhí)行的時候都會導致一塊內存泄漏。

  2. 偶發(fā)性內存泄漏。發(fā)生內存泄漏的代碼只有在某些特定環(huán)境或操作過程下才會發(fā)生。常發(fā)性和偶發(fā)性是相對的。對于特定的環(huán)境,偶發(fā)性的也許就變成了常發(fā)性的。所以測試環(huán)境和測試方法對檢測內存泄漏至關重要。

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

  4. 隱式內存泄漏。程序在運行過程中不停的分配內存,但是直到結束的時候才釋放內存。嚴格的說這里并沒有發(fā)生內存泄漏,因為最終程序釋放了所有申請的內存。但是對于一個服務器程序,需要運行幾天,幾周甚至幾個月,不及時釋放內存也可能導致最終耗盡系統(tǒng)的所有內存。所以,我們稱這類內存泄漏為隱式內存泄漏。

  從用戶使用程序的角度來看,內存泄漏本身不會產生什么危害,作為一般的用戶,根本感覺不到內存泄漏的存在。真正有危害的是內存泄漏的堆積,這會最終消耗盡系統(tǒng)所有的內存。從這個角度來說,一次性內存泄漏并沒有什么危害,因為它不會堆積,而隱式內存泄漏危害性則非常大,因為較之于常發(fā)性和偶發(fā)性內存泄漏它更難被檢測到

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

  引起內存溢出的原因有很多種,小編列舉一下常見的有以下幾種:

  1.內存中加載的數(shù)據量過于龐大,如一次從數(shù)據庫取出過多數(shù)據;

  2.集合類中有對對象的引用,使用完后未清空,使得JVM不能回收;

  3.代碼中存在死循環(huán)或循環(huán)產生過多重復的對象實體;

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

  5.啟動參數(shù)內存值設定的過小

  內存溢出的解決方案:

  第一步,修改JVM啟動參數(shù),直接增加內存。(-Xms,-Xmx參數(shù)一定不要忘記加。)

  第二步,檢查錯誤日志,查看“OutOfMemory”錯誤前是否有其它異?;蝈e誤。

  第三步,對代碼進行走查和分析,找出可能發(fā)生內存溢出的位置。

  重點排查以下幾點:

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

  2.檢查代碼中是否有死循環(huán)或遞歸調用。

  3.檢查是否有大循環(huán)重復產生新對象實體。

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

  5.檢查List、MAP等集合對象是否有使用完后,未清除的問題。List、MAP等集合對象會始終存有對對象的引用,使得這些對象不能被GC回收。

  第四步,使用內存查看工具動態(tài)查看內存使用情況。

  擴展資料

  數(shù)據類型超過了計算機字長的界限就會出現(xiàn)數(shù)據溢出的情況。導致內存溢出問題的原因有很多,比如:

  (1) 使用非類型安全(non-type-safe)的語言如 C/C++ 等。

  (2) 以不可靠的方式存取或者復制內存緩沖區(qū)。

  (3)編譯器設置的內存緩沖區(qū)太靠近關鍵數(shù)據結構。

  因素分析

  1.內存溢出問題是 C 語言或者 C++ 語言所固有的缺陷,它們既不檢查數(shù)組邊界,又不檢查類型可靠性(type-safety)。眾所周知,用 C/C++ 語言開發(fā)的程序由于目標代碼非常接近機器內核,因而能夠直接訪問內存和寄存器,這種特性大大提升了 C/C++ 語言代碼的性能。只要合理編碼,C/C++應用程序在執(zhí)行效率上必然優(yōu)于其它高級語言。然而,C/C++ 語言導致內存溢出問題的可能性也要大許多。其他語言也存在內存溢出問題,但它往往不是程序員的失誤,而是應用程序的運行時環(huán)境出錯所致。

  2. 當應用程序讀取用戶(也可能是惡意攻擊者)數(shù)據,試圖復制到應用程序開辟的內存緩沖區(qū)中,卻無法保證緩沖區(qū)的空間足夠時(換言之,假設代碼申請了 N 字節(jié)大小的內存緩沖區(qū),隨后又向其中復制超過 N 字節(jié)的數(shù)據)。內存緩沖區(qū)就可能會溢出。想一想,如果你向 12 盎司的玻璃杯中倒入 16 盎司水,那么多出來的 4 盎司水怎么辦?當然會滿到玻璃杯外面了!

  3. 最重要的是,C/C++編譯器開辟的內存緩沖區(qū)常常鄰近重要的數(shù)據結構。假設某個函數(shù)的堆棧緊接在在內存緩沖區(qū)后面時,其中保存的函數(shù)返回地址就會與內存緩沖區(qū)相鄰。此時,惡意攻擊者就可以向內存緩沖區(qū)復制大量數(shù)據,從而使得內存緩沖區(qū)溢出并覆蓋原先保存于堆棧中的函數(shù)返回地址。這樣,函數(shù)的返回地址就被攻擊者換成了他指定的數(shù)值;一旦函數(shù)調用完畢,就會繼續(xù)執(zhí)行“函數(shù)返回地址”處的代碼。非但如此,C++ 的某些其它數(shù)據結構,比如 v-table 、例外事件處理程序、函數(shù)指針等,也可能受到類似的攻擊。

  好了今天小編的介紹就到這里了,希望對大家有所幫助!如果你喜歡記得分享給身邊的朋友哦!

相關文章:

1.sql內存溢出怎么解決

2.win10電腦提示內存不足怎么辦

3.手機外置內存卡受損怎么辦

4.電腦藍屏出現(xiàn)0x000000f4代碼怎么辦

5.電腦藍屏0x000000c4怎么辦

6.電腦藍屏代碼0x000000f怎么辦

67910