android 内存泄漏 超详细的demo展示//后续会持续更新


内存泄漏

当程序不再使用到内存时,释放内存失败而产生了无用的内存消耗。内存泄漏并不是指物理上的内存消失,这里的内存泄漏是指由程序分配的内存但是由于程序逻辑错误而导致程序失去了对该内存的控制,使得内存浪费。由此可见,内存泄漏可能会引发OOM(Out Of Memory)内存溢出的严重后果。所以有效地避免内存泄漏成为开发必须要掌握的技能之一。


LeakCanary介绍

在开发的过程中,内存泄漏的问题往往在不经意间就发生了,如何快速有效解决内存泄漏成为了一大难题,现在在Android开发的过程中,有一款开源插件LeakCanary由Square公司开发,这款插件针对内存泄漏问题来说堪称神器,可以快速的帮助开发人员找到哪个Activity中由泄漏的问题,还能精确到Acticvity中哪个对象造成泄漏。在build.gradle里dependencies中加上implementation 'com.squareup.leakcanary:leakcanary-android:1.5’然后同步sync now,然后在SkyWalkerApplication中初始化。

    public static RefWatcher getRefWatcher(Context context) {
     
         SkyWalkerApplication application = (SkyWalkerApplication) context.getApplicationContext();
   	 return application.mRefWatcher;
    }
    public RefWatcher mRefWatcher;//下面这句放在onCreate()方法中
    mRefWatcher = LeakCanary.install(this);

内存泄漏常见情况

(其中LCApplication是demo中继承Application的类)

线程引起泄漏

   public class TestActivity extends AppCompatActivity {
         
  	 private final static String TAG = "TestActivity ";     
 	 @Override    
 	 protected void onCreate(Bundle savedInstanceState) {
             		
		super.onCreate(savedInstanceState);        
	   	setContentView(R.layout.activity_test);        
	  	findViewById(R.id.text_cool).setOnClickListener(new View.OnClickListener() {
     
	   	@Override            
	 	public void onClick(View v) {
                     
	   		Log.d(TAG, "onClick: ");                
	   		finish();            
	  	}        
	   });        
	   new Thread(new Runnable() {
                 
	   	@Override            
	  	public void run() {
                    
	    		try {
                         
	    			Thread.sleep( 15000 );               
	     		} catch (InterruptedException e) {
           
	        	       e.printStackTrace();         
	    		}       
	  	}       
	}).start();  
   }  
   @Override
   protected void onDestroy() {
     
	super.onDestroy();
	RefWatcher refWatcher = LCApplication.getRefWatcher(this);
	refWatcher.watch(this);
   }}

LeakCanary的log:
D/LeakCanary: In com.kedacom.leakcanarytestdemo:1.0:1.
*com.kedacom.leakcanarytestdemo.TestActivity has leaked:
*GC ROOT thread java.lang.Thread. (named ‘Thread-286’)
*references com.kedacom.leakcanarytestdemo.TestActivity$2.this$0 (anonymous implementation of java.lang.Runnable)
*leaks com.kedacom.leakcanarytestdemo.TestActivity instance
*Retaining: 48 KB. ------线程泄漏是48KB 拿小本子记好,等会要考--------
*Reference Key: 0fdca733-46c3-4ce9-b11b-eba2590112f6
*Device: Suzhou_Keda_Technology kedacom mt sky100
*Android Version: 5.1.1 API: 22 LeakCanary: 1.5 00f37f5
*Durations: watch=5020ms, gc=123ms, heap dump=2265ms, analysis=21160ms

解决方案

  1. 写一个静态内部线程类:目的切断Activity对线程的强引用
  2. 在线程内部采用弱引用保存Context引用。
private static class MyThread extends Thread {
     
    WeakReference<TestActivity> mThreadActivityRef;
    public MyThread(TestActivity activity) {
     
        mThreadActivityRef = new WeakReference<TestActivity>(activity);
    }
    @Override
    public void run() {
     
        super.run();
        if (mThreadActivityRef == null)
            return;
        if (mThreadActivityRef.get() != null){
     
            try {
     
                Thread.sleep( 15000 );
            } catch (InterruptedException e) {
     
                e.printStackTrace();
            }
        }
    }
}

未完待续

你可能感兴趣的:(android,内存泄漏)