記憶體洩漏分析總結
阿新 • • 發佈:2019-01-28
記憶體洩露原因分析
在JAVA中JVM的棧記錄了方法的呼叫,每個執行緒擁有一個棧。線上程的執行過程當中,執行到一個新的方法呼叫,就在棧中增加一個記憶體單元,即幀(frame)。在frame中,儲存有該方法呼叫的引數、區域性變數和返回地址。然而JAVA中的區域性變數只能是基本型別變數(int),或者物件的引用。所以在棧中只存放基本型別變數和物件的引用。引用的物件儲存在堆中。 當某方法執行結束時,該方法對應的frame將會從棧中刪除,frame中所有區域性變數和引數所佔有的空間也隨之釋放。執行緒回到原方法繼續執行,當所有的棧都清空的時候,程式也就隨之執行結束。 而對於堆記憶體,堆存放著普通變數。在JAVA中堆記憶體不會隨著方法的結束而清空垃圾回收機制
垃圾回收(garbage collection,簡稱GC)可以自動清空堆中不再使用的物件。在JAVA中物件是通過引用使用的。如果再沒有引用指向該物件,那麼該物件就無從處理或呼叫該物件,這樣的物件稱為不可到達垃圾回收實現思想 如果持有物件的強引用,垃圾回收器是無法在記憶體中回收這個物件。
引用型別
在JDK 1.2以前的版本中,若一個物件不被任何變數引用,那麼程式就無法再使用這個物件。也就是說,只有物件處於可觸及(reachable)狀態,程式才能使用它。從JDK 1.2版本開始,把物件的引用分為4種級別,從而使程式能更加靈活地控制物件的生命週期。這4種級別由高到低依次為:強引用、軟引用、弱引用和虛引用。 1. 強引用(Strong reference)A a = new A(); SoftReference<A> srA = new SoftReference<A>(a);軟引用所指示的物件進行垃圾回收需要滿足如下兩個條件: 1.當其指示的物件沒有任何強引用物件指向它; 2.當虛擬機器記憶體不足時。 因此,SoftReference變相的延長了其指示物件佔據堆記憶體的時間,直到虛擬機器記憶體不足時垃圾回收器才回收此堆記憶體空間。 3. 弱引用(Weak Reference) 同樣的,軟引用的一般使用形式如下:
A a = new A(); WeakReference<A> wrA = new WeakReference<A>(a);WeakReference不改變原有強引用物件的垃圾回收時機,一旦其指示物件沒有任何強引用物件時,此物件即進入正常的垃圾回收流程。 4. 虛引用(Phantom Reference) 記憶體洩漏的8種原因
- 全域性程序(process-global)的static變數。這個無視應用的狀態,持有Activity的強引用的怪物。
- 活在Activity生命週期之外的執行緒。沒有清空對Activity的強引用。