1. 程式人生 > >Android面試準備:記憶體洩露和記憶體溢位

Android面試準備:記憶體洩露和記憶體溢位

概念

  1. 記憶體洩露:申請的記憶體沒有及時釋放掉,這樣的話就會造成程式能使用的記憶體資源越來越少,最終會導致系統無法再提供記憶體資源;
    譬如說,一個map裡面一直在新增新的物件,這樣的話就很有可能造成記憶體洩露。
  2. 記憶體溢位:就是要求分配的記憶體超出了系統提供的記憶體,系統不能滿足要求,而產生了溢位。
    譬如說:你申請的是一個存放int型別的資料,卻賦值給他一個long型別的資料。這就導致了記憶體溢位。

Java記憶體回收機制

  1. C++的記憶體回收機制:在C++ 裡面,對記憶體資源的申請啊、使用啊、還有釋放都需要程式設計師來負責。這樣的話很有可能因為程式原忘了釋放記憶體導致記憶體的洩露。
  2. Java 的話就提供了一個相應的記憶體回收機制——垃圾回收機制(GC:garbage collection)。
  3. Java中垃圾回收機制的原理是:當一個記憶體物件失去了所有的引用之後,GC 就可以將其回收。反過來說,如果這個物件還存在引用,那麼它將不會被 GC 回收。

記憶體洩露和溢位的幾種情況

  1. 堆記憶體溢位(outOfMemoryError:java heap space)
    譬如說一些物件本來不需要佔用堆記憶體空間了,但是它的引用一直存在,導致垃圾回收機制無法釋放物件的佔用空間。
  2. 方法區記憶體溢位(outOfMemoryError:permgem space)
    方法區主要存放的是類資訊、常量、靜態變數等, 所以如果程式載入的類過多,或者使用反射、gclib等這種動態代理生成類的技術,就可能導致該區發生記憶體溢位。
  3. 執行緒棧溢位(java.lang.StackOverflowError)
    執行緒棧時執行緒獨有的一塊記憶體結構,所以執行緒棧發生問題必定是某個執行緒執行時產生的錯誤,一般執行緒棧溢位是由於遞迴太深或方法呼叫層級過多導致的。

避免記憶體溢位和記憶體洩露的幾個注意事項

  1. 儘早釋放無用物件的引用

  2. 使用字串處理,避免使用String,應大量使用StringBuffer,每一個String物件都得獨立佔用記憶體一塊區域

  3. 儘量少用靜態變數,因為靜態變數存放在永久代(方法區),永久代基本不參與垃圾回收

  4. 避免在迴圈中建立物件

  5. 列表內容

開啟大型檔案或從資料庫一次拿了太多的資料很容易造成記憶體溢位,所以在這些地方要大概計算一下資料量的最大值是多少,並且設定所需最小及最大的記憶體空間值