Android中的内存泄漏
<!--学习中....-->
内存监测工具 DDMS
内存分析工具 MAT
=================================================
引起内存泄漏的常见原因:
1. Cursor没有关闭。
2.inputStream/outputStream未关闭
3.Bitmap对象不在使用时调用recycle()没有及时释放
如果一个Bitmap对象比较占内存,当它不在被使用的时候,可以调用Bitmap.recycle()方法回收此对象的像素所占用的内存
参考http://whatandroid.blog.51cto.com/2172732/874940
4. 构造Adapter时,没有使用缓存的 convertView
5.没有及时释放对象的引用。
1 private static Drawable sBackground; 2 3 @Override 4 protected void onCreate(Bundle state) { 5 super.onCreate(state); 6 7 TextView label = new TextView(this); 8 label.setText("Leaks are bad"); 9 10 if (sBackground == null) { 11 sBackground = getResources().getDrawable(R.drawable.large_bitmap); 12 } 13 label.setBackgroundDrawable(sBackground); 14 15 setContentView(label); 16 }
这段程序看起来很简单,但是却问题很大。当屏幕旋转的时候会有leak,即gc没法销毁activity
屏幕旋转的时候系统会销毁当前的activity。但是当drawable和view关联后,因为drawable 是静态变量,不会随着Activity的销毁而销毁,因此它对view的引用也会依然存在,即sBackground保存了label的引用,而label保存了activity的引用。既然drawable不能销毁,它所引用和间接引用的都不能销毁,这样系统就没有办法销毁当前的activity,于是造成了内存泄露。gc对这种类型的内存泄露是无能为力的。
以下内容转自stack overflow,关于静态变量何时会被销毁。只有当dvm关闭或process被杀死时才会,所以慎用static变量。
-------------------------------------------------------------------------------------------------------------------------------------------
Lets start with a bit of background: What happens when you start an application?
The OS starts a process and assigns it a unique process id and allocates a process table.A process start an instance of DVM(Dalvik VM); Each application runs inside a DVM.
A DVM manages class loading unloading, instance lifecycle, GC etc.
Lifetime of a static variable: A static variable comes into existence when a class is loaded by the JVM and dies when the class is unloaded.
So if you create an android application and initialize a static variable, it will remain in the JVM until one of the following happens:
1. the class is unloaded
2. the JVM shuts down
3. the process dies
Note that the value of the static variable will persist when you switch to a different activity of another application and none of the above three happens. Should any of the above three happen the static will lose its value.
参考一篇代码
public class ProgressTestActivity extends Activity { /** Called when the activity is first created. */ private static int a = 0; private static final String TAG = ProgressTestActivity.class.getSimpleName(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); a++; Log.d(TAG, "onCreate___" + a); } @Override protected void onDestroy() { Log.d(TAG, "onDestroy___" + a); super.onDestroy(); // android.os.Process.killProcess(android.os.Process.myPid()); } }
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
6. 进程引起的内存泄漏
参考http://winuxxan.blog.51cto.com/2779763/512179