Magren

Magren

Idealist & Garbage maker 🛸
twitter
jike

談談Android的內存洩漏和溢出

雖然在大學以來學習了一年多的安卓,已經可以完成一部分的需求,但是在 Android 這方面的底層知識和一些概念我應該不算非常了解,借著這個長假的機會打算好好熟悉下。

Android 內存洩漏#

內存洩漏是指保存了不可能再被訪問的變量引用,導致垃圾回收器無法回收內存。
也就是說:
在 Java 中有些對象的生命周期是有限的,當它們完成了特定的邏輯後會被回收,但是,如果在對象的生命周期本該被回收時,這個對象仍然還被別的對象所持有引用,那麼就會導致內存洩漏。
具體例子:

public class LeakAct extends Activity {  
    @Override
    protected void onCreate(Bundle savedInstanceState) {    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.aty_leak);
        test();
    } 
    
    public void test() {    
        new Thread(new Runnable() {      
            @Override
            public void run() {        
                while (true) {          
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }z
            }
        }).start();
    }
}

test 是一個非靜態內部類,當我們 finish 的時候,該實例不會真正銷毀,GC 機制也不會進行該實例的垃圾回收,因為 *** 匿名內部類和非靜態內部類持有外部類的強引用, *** 也就是說 test 持有外部 activity 的強引用,而 thread 內部 while (true) 是死循環,線程不會停止,對外部 activity 的強引用也不會消失。這樣就造成了內存洩漏。

解決方案

1. 將內部類變成靜態內部類;
2. 如果有強引用 Activity 中的屬性,則將該屬性的引用方式改為弱引用;
3. 在業務允許的情況下,當 Activity 執行 onDestory 時,結束這些耗時任務;

Android 內存溢出#

內存溢出指的是 APP 向系統申請超過最大閥值的內存請求,系統不會再分配多餘的空間,從而造成內存溢出

  • 典型的例子就是加載多張大圖,導致內存耗盡,可以對圖片進行適當的質量壓縮或者尺寸壓縮。
  • 當某個界面存在內存洩露,反復進入該界面,將導致一直有新對象創建但是無法回收,最終導致內存耗盡,造成內存溢出。
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。