8

我有一個複雜的戰鬥系統,它有一個父Activity和幾個子類,它們通過擴展Battle並將上下文傳遞給這些類來訪問BattleActivity的靜態變量。Android - 釋放分配的內存AnimationDrawable正在使用

這一切似乎工作正常,但我有一個從內存釋放我所有的AnimationDrawables問題。在戰鬥中總共可以使用24個DrawableAnimations。目前這是可以的,但是每當用戶遇到新的怪物時,就會有4個AnimationDrawables被添加到內存中,這會緩慢但隨意地導致我的應用程序崩潰並導致anb內存不足異常。

因此,我真的需要找到一種方法來釋放我的戰鬥系統在我退出後立即佔用的所有內存。目前,我正在索尼Z2上進行測試,當用戶進入戰鬥時,mmeory從91mb增加到230mb。戰鬥結束後,我需要將內存使用量降低到91MB。我已經添加了一些非常基本的代碼片段,讓您瞭解應用程序當前如何流動以及我想要釋放內存的內容。

public class Battle extends Activity 
{ 
    // I have several AnimationDrawables loaded into memory 
    // These are then assigned the relevent animation to a button swicthing between these animations throughout my battle 
    ImageButton btnChr1; 
    AnimationDrawable cAnimHit1; 
} 

//This is the use of one of those AnimationDrawables 
public class Battle_Chr_Anim extends Battle 
{ 
    protected Context ctx; 
    private ImageButton btnChr1; 
    AnimationDrawable cAnimHit1; 

    public Battle_Chr_Anim(Context c, ImageButton _btnChr1, AnimationDrawable _cAnimHit1) { 
     this.ctx = c; 
     this.btnChr1 = _btnChr1; 
     this.cAnimHit1 = _cAnimHit1; 
    } 

    // Bound the ImageButton 
    int id = ctx.getResources().getIdentifier("idle", "drawable", ctx.getPackageName()); 
    img_chr1.setBackgroundResource(id); 
    frameAnimation = (AnimationDrawable)img_chr1.getBackground(); 
    frameAnimation.start() 

    // Loaded into memory ready so I can swicth them over quickly when user attacks 
    int ca1 = ctx.getResources().getIdentifier("attack", "drawable", ctx.getPackageName()); 
    cAnimHit1 = (AnimationDrawable)chrHit1.getBackground(); 
    cAnimHit1.start(); 
} 

public class Battle_Ended extends Battle 
{ 
    protected Context ctx; 

    public Battle_Ended(Context c) { 
     this.ctx = c; 
    } 

    //This is a dialog popup when the user completes the battle closing the battle activty 
    void EndBattle() 
    { 
     ImageButton btnSubmit = (ImageButton)dialog.findViewById(R.id.imgBtnSubmit); 
     btnSubmit.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       Intent returnIntent = new Intent(); 
       setResult(RESULT_CANCELED, returnIntent); 
       RecyleAllAnimations(); 
       dialog.dismiss(); 
       ((Activity) ctx).finish(); 
      } 
     }); 
    } 

    void RecyleAllAnimations() 
    { 
     // I want all AnimationDrawables from memory here, I believe the below line removes the one currently in use, however I have no way of releasing the other animations sitting in memory. 
     img_chr1.setBackgroundResource(android.R.color.transparent); 
     System.gc(); 
    } 
} 
+0

你真的有靜態變量,你傳遞的應用程序上下文?我認爲他們會比你的drawables更早地殺死你的應用程序 – TheRedFox 2014-11-07 14:37:06

+0

是的,這僅僅是爲了我的對戰方面的事情,因爲我不想讓我所有的代碼都在同一個Activity中,只是擴展這個類,以便我仍然可以訪問UI。由於我需要能夠加載所有的AnimationDrawables之前加載活動,以便動畫可以流利當用戶進入戰鬥 – 2014-11-07 14:43:44

回答

0

首先我認爲,除非你離開,他們申報的範圍,你不能做任何AnimationDrawable回收。請勿在System.gc();上繼電器,並讓GC自動爲您釋放這些內存。

其訪問BattleActivity

的靜態變量,這是你的第一個錯誤。如果你使用靜態變量,即使你離開你的活動,他們都在那裏,你一定會得到OOM。

因此,我真的需要找到一種方法來釋放所有的內存我的 戰鬥系統一旦我退出。

如果您將所有變量聲明爲非靜態變量,那麼當您離開它們定義的範圍時,您將不會獲得OOM。儘管如果您在活動運行期間創建AnimationDrawable而沒有任何界限,您可能會得到OOM。

+0

我已經修改我的代碼,以便我不再使用靜態AnimationDrawable,但我仍然即使在活動被破壞並且用戶返回到遊戲地圖頁面之後也存在釋放內存的問題。任何其他想法? – 2014-11-10 14:26:56

+0

你現在有什麼問題? – mmlooloo 2014-11-10 18:36:19

+0

好簡單地把內存不是爲AnimatonDrawables發佈 – 2014-11-10 19:58:52

0

使用靜態Drawable(s)或View(s)將導致內存泄漏,因爲drawable是有狀態的。

您既可以檢查是否有任何其他靜態繪製對象(S)或視圖(S)和擺脫他們,或致電

drawable.setCallback(null); 

你不能再利用拖拉的對象,這是不是一個好的做法,以呼叫系統.gc()

看來你的應用程序正在遭受內存泄漏的地方,如果你嘗試了上面的內存,並且內存仍然以這個速度擴展,那麼考慮使用memory analysis來縮小問題的範圍。

+0

我不認爲這是我遭受內存泄漏的事實,我認爲它是可剪切使用的內存剪切量。我的意思是在一個負載中,我需要加載30個AnimationDrawable,每個包含大約15個圖像,每個256px x 256px。因此,正如預期的那樣,內存使用率會上升(根據設備加載也需要2-4秒)。這我可以處理,但是,這是我需要以某種方式釋放內存。當每遇到一個新怪物時,另外5個AnimationDrawables被添加到內存中 – 2014-11-13 11:17:36

+0

這是真的,但是如果你的Activity沒有泄漏,內存應該根據需要釋放,如果你在關閉活動後手動調用System.gc()那些Drawable (s)應該從內存中清除,除非有泄漏。 如果除了確保沒有使用靜態Drawable(s)並且我提到的其他事情使它們在完成時指向null以避免可能的Loitering – 2014-11-13 11:33:22

+0

我想我今晚必須考慮今晚需要從所有ImageView中移除靜態然後ImageButtons可以正確測試它。什麼是檢查內存泄漏和內存分析工具的馬甲方式? – 2014-11-13 13:15:21