Java,Android内存泄漏代码片段
2015-08-19 18:17
1396 查看
一个生命周期长的对象引用了一个生命周期短的对象,导致短对象无法被回收
与流有关的溢出,比如流没有被关闭
与Context有关的溢出。
参考:Avoiding Memory Leak
对于需要Context的长期存在的对象,要使用ApplicataionContext,而不要使用Activity的Context,否则会导致Activity无法被回收。
使用Activity的Context的对象的生命周期要和Activity一致。
不要在Activity内使用内部类,如果无法控制它的生命周期的话,使用静态内部类替代,并且用WeakReference引用外部的Activity。因为内部类会拿着外部类的引用,所以内部类有可能导致外部类无法被回收。
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /** * 这里需要一个回调对象,当前Activity实现了回调接口,并将当前Activity的引用传递给网络请求模块 * 当当前Activity被finish掉,但网络请求模块持有的Activity的引用还未释放(比如网络处理还未完成或者没有释放引用), * 这时就会造成Activity无法被GC回收,造成内存泄漏 */ netWorkManager.request(url,this); /** * 传递需要接口的对象就不会导致Activity泄漏了 */ netWorkManager.request(url, new NewworkCallBack() { @Override public void onSuccess() { } @Override public void onFail() { } }); } @Override public void onSuccess() { } @Override public void onFail() { } }
与流有关的溢出,比如流没有被关闭
public class MemoryLeakDemo extends Activity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /** * ref: http://stackoverflow.com/questions/9515465/strictmode-complains-about-inputstream-not-being-closed */ /** * 看BufferedInputStream和FileInputStream的源码可知,它们的构造函数里会报异常,FileInputStream或BufferedInputStream对象会生成, * 但 objectInputStream仍然为null,在finally代码块中就并不会close FileInputStream和BufferedInputStream对象 */ ObjectInputStream objectInputStream; File file; try { file = new File("demo/myfile"); objectInputStream = new ObjectInputStream(new BufferedInputStream(new FileInputStream(file)),STREAM_BUFFER_SIZE); ... } catch (IOException e) { e.printStackTrace(); }finally { closeQuietly(objectInputStream); } /** * 解决办法很简单 */ FileInputStream fileInputStream; BufferedInputStream bufferedInputStream; ObjectInputStream objectInputStream; File file; try { file = new File("demo/myfile"); fileInputStream = new FileInputStream(file); bufferedInputStream = new BufferedInputStream(fileInputStream,STREAM_BUFFER_SIZE); objectInputStream = new ObjectInputStream(bufferedInputStream); ... } catch (IOException e) { e.printStackTrace(); }finally { closeQuietly(fileInputStream); closeQuietly(bufferedInputStream); closeQuietly(objectInputStream); } } private void closeQuietly(InputStream is){ if(is != null){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } }
与Context有关的溢出。
参考:Avoiding Memory Leak
对于需要Context的长期存在的对象,要使用ApplicataionContext,而不要使用Activity的Context,否则会导致Activity无法被回收。
使用Activity的Context的对象的生命周期要和Activity一致。
不要在Activity内使用内部类,如果无法控制它的生命周期的话,使用静态内部类替代,并且用WeakReference引用外部的Activity。因为内部类会拿着外部类的引用,所以内部类有可能导致外部类无法被回收。
public class MemoryLeakDemo extends Activity{ private static Drawable sBackground; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /** * android应用中,对Context的不适当使用会造成Activity的无法被回收 * 比如此例中,large_bitmap是个大图片,这个Activity可能会启用多次,为了节省加载图片的时间,将其设成静态变量 * 这会提高速度,但会导致Activity无法被回收,因为View会作为Drawable的callback,Drawable拿着View的引用, * View又拿着Activity的引用。 * 解决方法可以是,在Activity退出时将Drawable的callback置为null */ TextView label = new TextView(this); label.setText("Leaks are bad"); if (sBackground == null) { sBackground = getDrawable(R.drawable.large_bitmap); } label.setBackgroundDrawable(sBackground); setContentView(label); } }
相关文章推荐
- Android之Bitmap图片的截屏、模糊处理、传递、使用
- Android中的onActivityResult和setResult方法的使用
- Android studio 优化
- android 点滴——AsyncTask 和 Handler 比较
- Android 点滴——Handler用法总结
- Android重力感应飘树叶,晃动掉元宝
- Android性能优化典范-第3季
- Android性能优化典范-第2季
- android opengl es 1.0 draw text
- android 特效头疼
- android shape使用
- Android笔记:数据储存
- Android插件技术——开篇
- windows 下搭建完成的android JNI程序
- Android studio 使用总结 (乱七八糟的细节)
- Android 多线程-----AsyncTask详解
- android 万能回调接口
- Android内存分析工具(二):DDMS
- Android ImageView的scaleType属性与adjustViewBounds属性
- Android开发必知--WebView加载html5实现炫酷引导页面