在android 项目开发过程中,不小心可能就会导致activity的内存泄露,即使用户在使用APP的时候并没有感受到内存泄露给APP带来毁灭性的奔溃,但我们开发者可以通过调试能够很明显的看到有些占用的内存死也GC不掉。

OK ,隔壁家老伍来讲解一个,老伍亲身经历的怪事,APP在启动时我们都有加启动页面,为了好看,有时还会添加一些动画效果,可怕的是启动页面是一张比较大点的图片,启动完以后Activity被finish()掉,我们的理想是希望启动页结束后,占用的内存也能过及时销毁,避免一些无谓的内存占用。怪就怪这块内存怎么GC都GC不掉,佛主啊,佛主,这是是为啥子罗。

笔者接下来找原因,java的内存回收机制还是很强大的,很明显这个快占用的内存一定还被某个对象引用着,代码分析下来启动页面时加了一个过度动画,项目中有一个Util类,类里面提供了两个静态成语变量

private static Animation alphaShowAnimation = null;
private static Animation alphaHideAnimation = null;

加载动画的方法public static void startViewLeftAnimation(final View view, boolean isShow, Contextcontext)

注意参数View被final 修饰了,函数体里面的方法实现

if (alphaHideAnimation == null) {
alphaHideAnimation = AnimationUtils.loadAnimation(context, R.anim.animation_hide);
}
alphaHideAnimation.setAnimationListener(new AnimationListener() {


@Override
public void onAnimationStart(Animation arg0) {
// TODO Auto-generated method stub
}


@Override
public void onAnimationRepeat(Animation arg0) {
// TODO Auto-generated method stub


}


@Override
public void onAnimationEnd(Animation arg0) {
// TODO Auto-generated method stub
view.setVisibility(View.GONE);
}
});

注意看在动画结束后调用了view.setVisibility(View.GONE),也就是说使用了Activity 传递过来的view ,那么问题来了alphaHideAnimation又是静态变量,它生命周期老长老长的,没出意外的话可以活500年,仔细分析在一个静态成员的变量中保留了Activity里面的一个视图,可恶的是视图中保留了Context的引用,这个时候就产生了一个对象长期被引用,导致Activity无法被GC掉,Activity占用的内存也无法被GC掉。这个时候内存溢出发生了。

建议动画少用静态成员,尽量保持生命周期在函授体内,使用静态成员时要检查有没有长期引用且需要销毁的对象。

这是一个简单的Actiivty内存溢出,可以通过代码逻辑就能够分析出来,复杂一点的我们使用Mat工具来分析。





更多相关文章

  1. 一句话锁定MySQL数据占用元凶
  2. Android合理管理内存
  3. Android几种Service常驻内存的小思路
  4. 如何在Android实现桌面清理内存简单Widget小控件
  5. Android常见的八种导致 APP 内存泄漏的问题
  6. Android静态注册广播和动态注册广播的区别
  7. Android缓存处理
  8. Android帧动画实现,防OOM,比原生动画集节约超过十倍的资源
  9. 总结Android(安卓)App内存优化之图片优化

随机推荐

  1. 如果至少有一条记录的值为1,则返回“是”
  2. 如何将这两个查询组合成1?
  3. 如何在一个查询中组合六个独立查询。表是
  4. mysql主从简单配置
  5. 从SQL字符串分割多桩分隔符
  6. 【转载】怎样把Oracle的数据导入到SQLSer
  7. sql2000在还原备份时,我发现我新的备份,
  8. mysql 压缩解压版 zip 安装 详细步骤 教
  9. mysql无法登陆修复
  10. SQL主键的外键问题