zoukankan      html  css  js  c++  java
  • Context内存泄露

    private static Drawable sBackground; 
        
    @Override
    protected void onCreate(Bundle state){ 
      super.onCreate(state); 
        
      TextView label =new TextView(this); 
      label.setText("Leaks are bad"); 
        
      if(sBackground ==null){ 
        sBackground = getDrawable(R.drawable.large_bitmap); 
      } 
      label.setBackgroundDrawable(sBackground); 
        
      setContentView(label); 
    } 
    

    如上这段代码,context的内存泄露一般很隐蔽,但基本上是与静态变量相关的,如上代码中,TextView使用了静态对象sBackground,在框架中,TextView对象会通过callback的形式回传给sBackground,而TextView对象引用了Context实例,这就导致了当Activity调用onDestroy关闭的时候,Activity内存不会被销毁,而是直到静态变量sBackground被回收的时候才会销毁。从而引起了context的内存泄露。

    这个泄露问题在android3.0之后已被修复,因为3.0开始callback使用了弱引用保存对象。

    还有一个隐藏的context内存泄露如下:

    public class MainActivity extends Activity{
    	static Demo sInstance = null;
    	
    	@Override
    	public void onCreate(Bundle savedInstanceState){
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		if(sInstance == null){
    			sInstance = new Demo();
    		}
    	}
    	
    	class Demo{
    		void doSomething(){
    		
    		}
    	}
    }
    

     由于内部类会持有外部类的实例,因此如上的静态变量sInstance依然会引起context内存泄露。

    另外一个常见的context泄露在于系统Service,我们在使用系统service的时候通常会传递给service当前activity的实例context,然而如果系统service本身持有静态变量,而静态变量又引用了context实例的话就会导致泄露。

      private static Context serviceContext = null;
      private static ColorManagerListener colorMgrListener;
    
      public static int connect(Context context, ColorManagerListener colorListener)
      {
        if ((context == null) || (colorListener == null)) {
          Log.e(TAG, "One of the parmeter passed is null");
          return -904;
        }
        colorMgrListener = colorListener;
        serviceContext = context;
    

     上面的代码段是第三方公司的service提供给我们的jar包,测试发现有context内存泄露。反编译jar包后发现serviceContext和colorMgrListener这两个静态变量直接持有了context对象,会导致context的内存泄露。

  • 相关阅读:
    CXF学习(2) helloworld
    foreach与Iterable学习
    java基础之JDBC八:Druid连接池的使用
    java基础之JDBC七:C3P0连接池的使用
    java基础之JDBC六:DBCP 数据库连接池简介
    java基础之JDBC五:批处理简单示例
    java基础之JDBC四:事务简单示例
    java基础之JDBC三:简单工具类的提取及应用
    java基础之JDBC二:原生代码基础应用
    java基础之JDBC一:概述及步骤详解
  • 原文地址:https://www.cnblogs.com/fordreamxin/p/5065005.html
Copyright © 2011-2022 走看看