雖然在大學以來學習了一年多的安卓,已經可以完成一部分的需求,但是在 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 向系統申請超過最大閥值的內存請求,系統不會再分配多餘的空間,從而造成內存溢出
- 典型的例子就是加載多張大圖,導致內存耗盡,可以對圖片進行適當的質量壓縮或者尺寸壓縮。
- 當某個界面存在內存洩露,反復進入該界面,將導致一直有新對象創建但是無法回收,最終導致內存耗盡,造成內存溢出。