Android中内存泄漏的几种情况
来源:互联网 发布:淘宝保养品店铺推荐 编辑:程序博客网 时间:2024/06/06 01:01
1.单例造成的内存泄漏;
Android中单例模式中的饿汉式写法如下:
public class Example
{
private static Example Instance;
private Example(Context context)
{
this.context = context;
}
public static Example getInstance(Context context)
{
if(instance == null)
{
synchroized(Example.class)
{
if(instance == null)
{
instance = new Example(context);
}
}
}
return instance;
}
}
或者我们平时最常用到的单例模式
public class Example
{
private static Example Instance;
private Example(Context context)
{
this.context = context;
}
public static Example getInstance(Context context)
{
if(instance == null)
{
instance = new Example(context);
}
return instance;
}
}
我们在activity中调用getInstance()并传入this时,Example中便持有activity的引用,当activity退出时,activity无法会回收,就会造成内存泄漏.正确的写法是在Example的构造方法中做出如下修改:
private Example(Context context)
{
this.context = context.getapplicationcontext;
}
这样修改以后,通过context获取到Application的context,当activity销毁时,activity便能被正常回收,不会造成内存泄漏,而Application的生命周期与Example类是一致的.2.外部类中持有非静态内部类的静态对象
看下面一段代码:
public class Mainactivity extend fragmentactivity
{
private static Example instance;
protected void onCreate(Bundle bundle)
{
super.onCreate(bundle);
setContentView(R.layout.activityman);
instance = new Example();
}
public class Example
{
}
}
mainactivity中创建了Example的静态对象,从而Example持有了activity的引用,在activity销毁时无法被回收,从而造成内存泄漏,解决的方法是instance修改为非静态对象,,或者把Example修改为静态内部累,从未避免造成内存泄漏.
3.Handle和Runnable作为非静态内部类
我们在使用Handler或new Runnable时,通常使用匿名内部类的形式,即直接new出一个对象进行一些延时操作,如果在延时等待过程中,activity被销毁了,此时acitivity无法被销毁并回收,会造成内存泄漏.在写代码时,应该将Handler或Runnable定义为静态内部类,然后在activity中new出这些类的对象,再进行延时操作.
然后最好在onDestory()中调用handler.removecallbacks(runnable)取消定时操作,这样在acitivity销毁后, 也不会触发run()方法.
Note:还有一种比较少见的情况,就是在Handler或Runnable的构造方法中需要Context对象,在activity中调用Handler或Runnable类创建对象并传入this时,Handler或Runnable也会持有acitivity的引用,同样会造成内存泄漏.修改方法是使用若引用传入context,代码如下:
private class Mainactivity extend FragmentActivity{
private MyHandler mHandler = new Handler(new WeakPreference<Context>(this));
public statci class MyHandler exend Handle
{
private Context context;
public MyHandler(WeakPreference<Context> weakPreference)
{
context =weakPreference.get().
}
}
}
4.还有一些其他的违规操作会造成内存泄漏,如BroadcastReceiver,inputstream,cource使用后未及时unregisterReceiver或关闭,都会造成内存泄漏.
造成内存泄漏的主要原因是长生命周期持有短生命周期的引用,短生命周期在周期结束时,长生命周期仍然存在,导致无法被回收,从而造成内存泄漏.
看了郭神的文章,感觉这几点比较重要,在垒代码的时候需要特别注意,特别记录下来.
- Android中内存泄漏的几种情况
- C++中内存泄漏的几种情况
- C++中内存泄漏的几种情况
- C++中内存泄漏的几种情况
- 内存泄漏的几种情况
- 内存泄漏的几种情况
- 内存泄漏的几种情况
- js内存泄漏的几种情况
- C++内存泄漏的几种情况
- C++中内存泄漏浅谈几种情况(二)
- Android内存泄漏的情况
- 可能出现内存泄漏的几种情况
- 导致JS内存泄漏的几种情况
- Android内存泄漏的几种可能
- Android几种常见的内存泄漏
- Android 常见的几种内存泄漏
- Android 常见的几种内存泄漏
- Android 几种常见的内存泄漏
- JQuery的ajaxFileUpload的使用
- Gcc编译器
- 123
- android抽奖大转盘
- 使用nginx的gzip大幅度提升页面的加载速度
- Android中内存泄漏的几种情况
- 3个 优秀Linux 网络监视器!
- cmake使用方法
- lane-detection-evaluation
- ElasticSearch读流程
- 基于自定义消息结构体的远程控制软件的实现
- 【Java Web】MVC(一)初识SpringMVC
- Qt--编译与安装
- 安装kinect v1驱动和kinect v2驱动,适合新手入门