一、什么是内存泄漏?



  • 无用的对象没有被及时释放引用,导致GC无法回收,就有可能出现内存泄漏。


二、内存泄漏带来的危害是什么?



  • 内存泄漏会增加内存占用和OOM几率。


三、哪些代码的写法会导致内存泄漏?



  • 常见五种导致 APP 内存泄漏的地方
  1. 静态 Activity
    泄漏 activity 最简单的方法就是在 activity 类中定义一个 static 变量,并且将其指向一个运行中的 activity 实例。如果在 activity 的生命周期结束之前,没有清除这个引用,那它就会泄漏了。这是因为 activity(例如 MainActivity) 的类对象是静态的,一旦加载,就会在 APP 运行时一直常驻内存,因此如果类对象不卸载,其静态成员就不会被垃圾回收。


void setStaticActivity() {
      activity = this;
    }

    View saButton = findViewById(R.id.sa_button);
    saButton.setOnClickListener(new View.OnClickListener() {
      @Override public void onClick(View v) {
            setStaticActivity();
            nextActivity();
      }
    });

2. 内部类或者匿名内部类
类似的,匿名类同样会持有定义它们的对象的引用。因此如果在 activity 内定义了一个匿名的 AsyncTask 对象,就有可能发生内存泄漏了。如果 activity 被销毁之后 AsyncTask 仍然在执行,那就会组织垃圾回收器回收 activity 对象,进而导致内存泄漏,直到执行结束才能回收 activity。



void startAsyncTask() {
        new AsyncTask<Void, Void, Void>() {
            @Override protected Void doInBackground(Void... params) {
                while(true);
            }
        }.execute();
    }

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    View aicButton = findViewById(R.id.at_button);
    aicButton.setOnClickListener(new View.OnClickListener() {
        @Override public void onClick(View v) {
            startAsyncTask();
            nextActivity();
        }
    });

3. Handlers
同样的,定义一个匿名的 Runnable 对象并将其提交到 Handler 上也可能导致 activity 泄漏。Runnable 对象间接地引用了定义它的 activity 对象,而它会被提交到 Handler 的 MessageQueue 中,如果它在 activity 销毁时还没有被处理,那就会导致 activity 泄漏了。



void createHandler() {
        new Handler() {
            @Override public void handleMessage(Message message) {
                   super.handleMessage(message);
                }
            }.postDelayed(new Runnable() {
                @Override public void run() {
                        while(true);
                }
          }, Long.MAX_VALUE >> 1);
    }

    View hButton = findViewById(R.id.h_button);
    hButton.setOnClickListener(new View.OnClickListener() {
    @Override public void onClick(View v) {
        createHandler();
        nextActivity();
        }
});

4. EditText

EditText所处的上下文对象会一直保留在(4.0.x,4.1.x,4.2.x)的系统版本中。大家在用着它这么长的时间不知道系统还有这么个bug(具体可参考:https://dddpaul.github.io/blog/2014/08/01/android-memory-leaks/),但好在Android 4.3, API 18的系统版本上修复了该问题,但是对于18以下的就要注意啦,需要做些特殊处理,不然就会导致泄漏的,其实解决办法也是很简单:修改EditText的android:inputType= “textNoSuggestions”

泄露的具体信息如图:

android 6 程序内存数据被Dump风险 android内存泄露会怎么样_内存泄漏



  1. Threads
    同样的,使用 Thread 和 TimerTask 也可能导致 activity 泄漏。


void spawnThread() {
        new Thread() {
            @Override public void run() {
                  while(true);
            }
        }.start();
    }

    View tButton = findViewById(R.id.t_button);
    tButton.setOnClickListener(new View.OnClickListener() {
      @Override public void onClick(View v) {
          spawnThread();
          nextActivity();
      }
    });