内存——静态变量导致内存泄漏

转载 2016年08月29日 13:54:18

转自http://blog.csdn.net/u012810020/article/details/51726699

1、要不怎么说static关键字要慎用呢?来看看下面这段代码,Context对象为静态的,那么Activity就无法正常销毁,会常驻内存。

    public class MainActivity extends Activity{  
        public static Context mContext;  
        @Override  
        protected void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.activity_main);  
            mContext = this;  
        }  
    }  
解决办法:1使用Application的Context。 2慎用statistic关键字


2、单例模式导致内存的泄漏

静态变量导致的内存泄漏太过明显,而单例模式带来的内存的泄漏容易被忽略。

    **  
     * Created by lizhenya.  
     */  
    public class DensityConvertUtils {  
        private DensityConvertUtils() {  
            /* cannot be instantiated */  
            throw new UnsupportedOperationException("cannot be instantiated");  
        }  
      
        /**  
         * dp转px  
         *  
         * @param context  
         * @param dpVal  
         * @return  
         */  
        public static int dp2px(Context context, float dpVal) {  
            return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,  
                    dpVal, context.getResources().getDisplayMetrics());  
        }  
      
        /**  
         * sp转px  
         *  
         * @param context  
         * @param spVal  
         * @return  
         */  
        public static int sp2px(Context context, float spVal) {  
            return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,  
                    spVal, context.getResources().getDisplayMetrics());  
        }  
    }  

我们在使用的时候经常会犯一些错误:

    /**  
     * Created by lizhenya.  
     */  
    public class HomeActivity extends Activity {  
        Button btn_home;  
        @Override  
        protected void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            requestWindowFeature(Window.FEATURE_NO_TITLE);  
            setContentView(R.layout.layout_home);  
            DensityConvertUtils.dp2px(HomeActivity.this,20);  
        }  
    }  
单例模式的特点就是它的生命周期和Application一样,那么如果某个Activity实例被一个单例所持有,也就是说在单例里面引用了它,那么就会造成Activity对象无法正常回收释放。所以我们尽量的使用Application的全局Context。


3,属性动画导致的内存泄漏

    从Android3.0开始,Google提供了属性动画,属性动画中有一类无限循环的动画,如果在Activity中播放此类动画并且在onDestroy()方法中没有停止该动画,那么动画会一直循环下去,尽管在界面上已经无法看不到动画了,但这个时候Activity的View会被动画持有,而View又持有Activity,最终Activity无法释放。下面的动画是无限循环的,会泄露当前的Activity。

    /**  
     * Created by lizhenya.  
     */  
    public class HomeActivity extends Activity {  
        Button btn_home;  
      
        @Override  
        protected void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            requestWindowFeature(Window.FEATURE_NO_TITLE);  
            setContentView(R.layout.layout_home);  
            btn_home = (Button) findViewById(R.id.btn_home);  
            ObjectAnimator animator = ObjectAnimator.ofFloat(btn_home, "ratation", 0, 360).setDuration(2000);  
            animator.setRepeatCount(ValueAnimator.INFINITE);  
            animator.start();  
        }  
    }  

解决方案:

    在当前Activity的onDestroy()方法中取消动画:animator.cancel()。

    /**  
     * Created by lizhenya.  
     */  
    public class HomeActivity extends Activity {  
        private Button btn_home;  
        private ObjectAnimator animator;  
      
        @Override  
        protected void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            requestWindowFeature(Window.FEATURE_NO_TITLE);  
            setContentView(R.layout.layout_home);  
            btn_home = (Button) findViewById(R.id.btn_home);  
      
            animator = ObjectAnimator.ofFloat(btn_home, "ratation", 0, 360).setDuration(2000);  
            animator.setRepeatCount(ValueAnimator.INFINITE);  
            animator.start();  
        }  
      
        @Override  
        protected void onDestroy() {  
            super.onDestroy();  
            animator.cancel();  
        }  
    }  




内存泄漏优化---静态变量导致内存泄漏

1、要不怎么说static关键字要慎用呢?来看看下面这段代码,Context对象为静态的,那么Activity就无法正常销毁,会常驻内存。 public class MainActivity ext...

C# 中动态方法与静态方法的误区

误区一、 静态方法常驻内存,实例方法不是,所以静态方法效率高但占内存。 事实上,方法都是一样的,在加载时机和占用内存上,静态方法和实例方法是一样的,在类型第一次被使用时加载。调用的速度基本上没有差别。...

static关键字所导致的内存泄漏问题

大家都知道内存泄漏和内存溢出是不一样的,内存泄漏所导致的越来越多的内存得不到回收的时候,最终就有可能导致内存溢出,下面说一下使用static属性所导致的内存泄漏的问题。 在dalvik虚拟机中,sta...

android中不小心使用静态变量会导致内存泄露

在android 项目开发过程中,不小心可能就会导致activity的内存泄露,即使用户在使用APP的时候并没有感受到内存泄露给APP带来毁灭性的奔溃,但我们开发者可以通过调试能够很明显的看到有些占用...
  • wuchuy
  • wuchuy
  • 2016年04月25日 15:39
  • 2975

php面向对象基础概念(接口)

什么是接口(interface) ? 接口是方法的抽象,如果不同的类有同样的方法,那么就应该考虑使用接口。  (1)接口是一个行为的规范、协议。其实就是类和类之间的一种协定,一种约束 (2)C#不支...

php中对象,类与内存的关系

内存分为4个部分 数据段,栈段,代码段,堆段。 栈是先进后出,而且分配的内存很少,但是速度很快,通常用于保存一些标量,例如(int,string,boolean)因为这些已经知道他的内存大小,所以...

【JAVA优化编程】内存管理之——(5)共享静态变量存储空间

5  共享静态变量存储空间     我们知道类中的静态变量(Static Variable)在程序运行期间其内存空间对所有该类的对象实例而言是共享的,因此在某些时候为了节省系统内存开销,共享资源,将...

Android —— 静态AsyncTask解决内存泄漏

Android中我们经常需要开启子线程去获取网络数据,或者说做一些耗时操作,开发者经常使用的就是AsyncTask,Android 1.5提供的工具类AsyncTask使我们创建异步线程更加便捷。如果...

c++数据结构—————静态链表防止内存泄漏

**在写静态链表的时候如果new了一个新的动态数组来做数组增长,不及时删除原数组 在短期内不会太大影响 但是积累会造成内存泄漏(大量的堆内存被没有引用的new数组占据) 所以要及时释放掉new的动态数...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:内存——静态变量导致内存泄漏
举报原因:
原因补充:

(最多只允许输入30个字)