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