没有合适的资源?快使用搜索试试~ 我知道了~
首页Android内存优化——常见内存泄露及优化方案.pdf
Android内存优化——常见内存泄露及优化方案.pdf
需积分: 31 491 浏览量
更新于2023-05-23
评论 1
收藏 251KB PDF 举报
主要处理一些有关Android内存泄露案例以及解决方案,比如我们常见的单例模式、listView的的优化
资源详情
资源评论
资源推荐

Android 内存优化——常见内存泄露及优化方案
如果一个无用对象(不需要再使用的对象)仍然被其他对象持有引用,造成该对象无法被系统回
收,以致该对象在堆中所占用的内存单元无法被释放而造成内存空间浪费,这中情况就是内存泄
露。
在 Android 开发中,一些不好的编程习惯会导致我们的开发的 app 存在内存泄露的情况。下面介
绍一些在 Android 开发中常见的内存泄露场景及优化方案。
单例导致内存泄露
单例模式在 Android 开发中会经常用到,但是如果使用不当就会导致内存泄露。因为单例的静态
特性使得它的生命周期同应用的生命周期一样长,如果一个对象已经没有用处了,但是单例还持
有它的引用,那么在整个应用程序的生命周期它都不能正常被回收,从而导致内存泄露。
public class AppSettings {
private static AppSettings sInstance;
private Context mContext;
private AppSettings(Context context) {
this.mContext = context;
}
public static AppSettings getInstance(Context context) {
if (sInstance == null) {
sInstance = new AppSettings(context);
}
return sInstance;
}
}
像上面代码中这样的单例,如果我们在调用 getInstance(Context context)方法的时候传入的
context 参数是 Activity、Service 等上下文,就会导致内存泄露。

以 Activity 为例,当我们启动一个 Activity,并调用 getInstance(Context context)方法去获取
AppSettings 的单例,传入 Activity.this 作为 context,这样 AppSettings 类的单例 sInstance 就
持有了 Activity 的引用,当我们退出 Activity 时,该 Activity 就没有用了,但是因为 sIntance
作为静态单例(在应用程序的整个生命周期中存在)会继续持有这个 Activity 的引用,导致这个
Activity 对象无法被回收释放,这就造成了内存泄露。
为了避免这样单例导致内存泄露,我们可以将 context 参数改为全局的上下文:
private AppSettings(Context context) {
this.mContext = context.getApplicationContext();
}
全局的上下文 Application Context 就是应用程序的上下文,和单例的生命周期一样长,这样就避
免了内存泄漏。
单例模式对应应用程序的生命周期,所以我们在构造单例的时候尽量避免使用 Activity 的上下文,
而是使用 Application 的上下文。
静态变量导致内存泄露
静态变量存储在方法区,它的生命周期从类加载开始,到整个进程结束。一旦静态变量初始化后,
它所持有的引用只有等到进程结束才会释放。
比如下面这样的情况,在 Activity 中为了避免重复的创建 info,将 sInfo 作为静态变量:
public class MainActivity extends AppCompatActivity {
private static Info sInfo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (sInfo != null) {
sInfo = new Info(this);
}
}
}

class Info {
public Info(Activity activity) {
}
}
Info 作为 Activity 的静态成员,并且持有 Activity 的引用,但是 sInfo 作为静态变量,生命周期
肯定比 Activity 长。所以当 Activity 退出后,sInfo 仍然引用了 Activity,Activity 不能被回收,
这就导致了内存泄露。
在 Android 开发中,静态持有很多时候都有可能因为其使用的生命周期不一致而导致内存泄露,
所以我们在新建静态持有的变量的时候需要多考虑一下各个成员之间的引用关系,并且尽量少地
使用静态持有的变量,以避免发生内存泄露。当然,我们也可以在适当的时候讲静态量重置为 null,
使其不再持有引用,这样也可以避免内存泄露。
非静态内部类导致内存泄露
非静态内部类(包括匿名内部类)默认就会持有外部类的引用,当非静态内部类对象的生命周期
比外部类对象的生命周期长时,就会导致内存泄露。
非静态内部类导致的内存泄露在 Android 开发中有一种典型的场景就是使用 Handler,很多开发
者在使用 Handler 是这样写的:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start();
}
private void start() {
Message msg = Message.obtain();
msg.what = 1;
mHandler.sendMessage(msg);
}
剩余11页未读,继续阅读














安全验证
文档复制为VIP权益,开通VIP直接复制

评论0