android编译非静态内部类,Android 非静态内部类/匿名类引起的内存泄漏
一、概述
讓我們先來回顧一下android內存泄漏的相關概念:
內存溢出:android系統會給每個安卓程序分配一定的內存,當程序所使用的內存超過最大值就會造成內存溢出,就是常說的OOM
內存泄漏:簡單來說就是你new了一個對象,這個對象是要消耗內存的,然后jvm會對沒有引用的對象進行回收釋放內存,如果一個對象已經沒有引用了,但是jvm沒有回收這個對象,就會造成內存泄漏,多次內存泄漏到最后就會變成內存溢出。
二、內存泄漏
常見的內存泄漏有很多種:
1. 非靜態(tài)內部類/匿名內部類的靜態(tài)實例容易造成內存泄漏
2. 單例模式導致的內存泄漏
3. 對該解注冊、注銷、清空的對象沒有及時做這樣操作導致的,比如說廣播、服務、io流等等。(其實我個人覺得這一條的最終原因還是第一條,因為說到底還是引用沒有釋放使jvm沒有不能回收)
三、非靜態(tài)內部類/匿名內部類的靜態(tài)實例容易造成內存泄漏
綜上所述,我們來重點理解一下非靜態(tài)內部類/匿名內部類的靜態(tài)實例容易造成內存泄漏,因為以前作者在了解android內存泄漏方面的知識的時候,對于網上帖子整理出來的常見內存泄漏的例子,我會更多的嘗試把它們記住。。因為根本不理解是為什么會造成內存泄漏,所以效率非常低,而且真正碰到了的時候也發(fā)現不了。
java內部類分為四種
靜態(tài)內部類
靜態(tài)匿名內部類
非靜態(tài)內部類
非靜態(tài)內部匿名類
/**
* 人類
*/
public class Human {
private static int age = 1;// 年齡
private String name;// 姓名
// 內部類
public class Man{}
// 靜態(tài)內部類
public static class WoMan{}
public void setMan(Man man){}
public void setWoMan(WoMan woMan){}
public void test(){
Human human = new Human();
// 向human對象setMan方法中傳入一個匿名的Man對象
human.setMan(new Man());
// 這種方式和上面的方式其實是一樣的,大家應該可以看的出來
// 上面的方式就是我們常用的控件事件監(jiān)聽
Man man = new Man();
human.setMan(man);
// 向human對象setWoMan方法中傳入一個匿名的Man對象
human.setWoMan(new WoMan());
}
}
你們可能會問,靜態(tài)內部類和非靜態(tài)內部類到底有什么關系呢?靜態(tài)變量大家都會用吧:
private static int age = 1;// 年齡
static的東西就代表是直接丟內存的,就是我們常說的緩存,順便說一句,程序Exception的時候是會清空內存的。
拿上面的例子來說,Human類有一個靜態(tài)的變量age,也就是說age是所有Human對象所共享的,換句話說是整個人類都有相同的年齡。而類成員變量name就只屬于單個Human對象,每個人有屬于他自己的名字,并不是共享的。通過這個例子好好理解一下static這個修飾符的概念,后面還會提到。
在Java中,非靜態(tài)內部類/匿名類會隱式的持有外部類的引用,像這段代碼:
human.setMan(new Man());
Man man = new Man();
human.setMan(man);
這樣寫是沒有問題的,內部類隱式持有外部引用,生命周期是相同的,不會造成內存泄漏,但是我們來修改一下:
// 在Human里面定義一個static的Man變量
private static Man whiteMan;// 白人
然后:
whiteMan = new Man();
在test()方法中初始化這個whiteMan,此時,whiteMan是持有持有外部類Human的隱式引用,但是whiteMan是static的,static修飾的變量是放在內存中,生命周期是超過Human的,此時就已經發(fā)生了內存泄漏,類似的android中常見的內存泄漏:
public class MyActivity extends AppCompatActivity {
private static Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
context = this;
}
}
這是最基本常見的內存泄漏,通過我們那面的Human類的例子來理解一下這個內存泄漏,首先Activity就相當于Human類,然后static修飾的Context就相當于whiteMan,這個Context是持有Activity的引用的,它的生命周期是超過Activity的,并且這個本該被回收的activty由于它還一直存在著,這就導致了內存泄漏。
解決辦法:把上述例子中的Man加上static修飾,如同WoMan。
用靜態(tài)內部類/匿名類替換非靜態(tài)內部類/匿名類,因為靜態(tài)內部類/匿名類不會隱式的持有外部類引用,外部類會以正常的方式回收。
四、總結
關鍵詞:static,原理:存放在內存中。如果像前面的Human類中那樣的話,一個靜態(tài)的變量是屬于所有Human類的實例,而不是屬于單個實例。
總結
以上是生活随笔為你收集整理的android编译非静态内部类,Android 非静态内部类/匿名类引起的内存泄漏的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android关键应用程序,安卓开发:A
- 下一篇: android实现首页倒计时,andro