2011-12-09 65 views
6

我最近已經瞭解到有多少內存可能會因泄漏上下文而浪費掉,以及如何在屏幕方向更改後使用內存轉儲測試此類泄漏。新活動應該被實例化和創建,最初的銷燬和收集。然而,除非我的內存泄漏並沒有看到它,進行下列活動,似乎並沒有被收集,如果它開始進行不同的活動和破壞自己:測試Android應用程序中的內存泄漏

public class Foo extends Activity { 
    private Button button; 

    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     button = new Button(this); 
     button.setOnClickListener(new OnClickListener() { 
      public void onClick(View view) { 
       startActivity(new Intent(Foo.this, Bar.class)); 
       finish(); 
      } 
     }); 

     setContentView(button); 
    } 

    protected void onDestroy() { 
     super.onDestroy(); 

     button.setOnClickListener(null); 

     Log.e("you're it", "isFinishing() == " + isFinishing()); 
    } 
} 

 

public class Bar extends Activity { 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     TextView textView = new TextView(this); 
     textView.setText("hello, world"); 

     setContentView(textView); 
    } 
} 

這裏的內存轉儲信息,點擊該按鈕啓動欄,並要求垃圾收集後幾次採取:

Class Name            | Shallow Heap | Retained Heap 
---------------------------------------------------------------------------------------- 
com.test.testProject.Foo @ 0x4135b188     |   184 |   2,208 
mOuterContext android.app.ContextImpl @ 0x4135b390  |   96 |   392 
    <Java Local> java.lang.Thread @ 0x40996460 main Thread|   80 |   1,416 
    mContext android.media.AudioManager @ 0x4135b480  |   48 |   176 
---------------------------------------------------------------------------------------- 

基於this,我認爲在活動之間投擲額外的成品會使第一個人有資格收集並允許我以另外的方式測試泄漏,這是否合理?我是否在泄漏記憶? Android有什麼理由要保持這種被破壞的活動?

+1

你沒有內存泄漏。我相信GC根本還沒有決定清理該活動 - 即使您已經要求垃圾收集。你在測試它的什麼版本的Android?我認爲如果你在3.0+上嘗試同樣的事情,GC會更快地將其刪除 – Wozza

+0

也許在分析轉儲文件時檢查「Intent」對象仍處於活動狀態。它可能會指向Foo和Bar。 – Wozza

+0

這是在4.0平臺上。此外,還有兩個Intent實例,一個由Foo引用,另一個由Bar引用。我認爲這是有道理的,因爲每個Activity都有一個對它的getIntent()的Intent的引用。這不是維持活動的意圖,是嗎? – lwiseman

回答

0

也許ü可以試試下面的代碼:

button.setOnClickListener(new OnClickListener() { 
     public void onClick(View view) { 
      startActivity(new Intent(getApplicationContext(), Bar.class)); 
      finish(); 
     } 
    });