1. 程式人生 > >關於記憶體溢位和記憶體洩漏的討論

關於記憶體溢位和記憶體洩漏的討論

  • 什麼是記憶體洩漏?

  1. 程式的執行需要記憶體。只要程式提出要求,作業系統或者執行時(runtime)就必須供給記憶體。

    不再用到的記憶體,沒有及時釋放,就叫做記憶體洩漏(memory leak),對於持續執行的服務程序(daemon),必須及時釋放不再用到的記憶體。否則,記憶體佔用越來越高,輕則影響系統性能,重則導致程序崩潰。

  2. 有些語言(比如 C 語言)必須手動釋放記憶體,程式設計師負責記憶體管理。

  • 常發性記憶體洩漏。發生記憶體洩漏的程式碼會被多次執行到,每次被執行的時候都會導致一塊記憶體洩漏。 
  •  偶發性記憶體洩漏。發生記憶體洩漏的程式碼只有在某些特定環境或操作過程下才會發生。常發性和偶發性是相對的。對於特定的環境,偶發性的也許就變成了常發性的。所以測試環境和測試方法對檢測記憶體洩漏至關重要。 
  •  一次性記憶體洩漏。發生記憶體洩漏的程式碼只會被執行一次,或者由於演算法上的缺陷,導致總會有一塊僅且一塊記憶體發生洩漏。比如,在類的建構函式中分配記憶體,在解構函式中卻沒有釋放該記憶體,所以記憶體洩漏只會發生一次。 
  •  隱式記憶體洩漏。程式在執行過程中不停的分配記憶體,但是直到結束的時候才釋放記憶體。嚴格的說這裡並沒有發生記憶體洩漏,因為最終程式釋放了所有申請的記憶體。但是對於一個伺服器程式,需要執行幾天,幾周甚至幾個月,不及時釋放記憶體也可能導致最終耗盡系統的所有記憶體。所以,我們稱這類記憶體洩漏為隱式記憶體洩漏。 
  • 什麼是記憶體溢位?

  1. 是指程式在申請記憶體時,沒有足夠的記憶體空間供其使用,出現out of memory;比如申請了一個integer,但給它存了long才能存下的數,那就是記憶體溢位。

  2. 一個盤子用盡各種方法只能裝4個果子,你裝了5個,結果掉倒地上不能吃了。這就是溢位!
  3. 比方說棧,棧滿時再做進棧必定產生空間溢位,叫上溢,棧空時再做退棧也產生空間溢位,稱為下溢。就是分配的記憶體不足以放下資料項序列,稱為記憶體溢位. 
  • 記憶體中載入的資料量過於龐大,如一次從資料庫取出過多資料;
  • 集合類中有對物件的引用,使用完後未清空,使得JVM不能回收;
  • 程式碼中存在死迴圈或迴圈產生過多重複的物件實體;
  • 使用的第三方軟體中的BUG;
  • 啟動引數記憶體值設定的過小