Android 性能优化--内存篇

本文详细介绍了Android应用的内存优化,包括内存泄漏的原因和类型,如单例模式、静态变量、非静态内部类等,以及对应的解决方案。同时,讨论了内存溢出问题,分析了可能导致内存溢出的因素,并提出了相应的处理策略。文章还涵盖了检测内存问题的工具,如Android Profiler、LeakCanary和TraceView,以及如何通过5R法则进行内存管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android内存优化是我们性能优化工作中比较重要的一环,主要包括两方面的工作:

  1. 优化RAM,即降低运行时内存。目的是防止程序发生OOM异常,以及降低程序由于内存过大被LowMemoryKiller(LMK)机制杀死的概率。同时,不合理的内存使用会使GC次数大大增多,从而导致程序变卡。
  2. 优化ROM,即降低程序占ROM的体积,防止ROM空间不足导致程序无法安装等问题。

前言

Android中关于内存优化的问题主要包括三个方面:

  • Memory Leaks 内存泄漏
  • OutOfMemory 内存溢出
  • Memory Churn 内存抖动

同时,和内存相关的三个主要数据为:

  • 总内存
  • 系统可用内存
  • 当前App可用内存

扩大内存

  1. 申请更大内存

每一个Android设备都会有不同的RAM总大小与可用空间,因此不同设备为App提供了不同大小的heap限制,可以通过调用getMemoryClass()来获取当前App的可用heap大小。

在一些特殊情景下,可以通过在manifest的application标签下添加largeHeap=true属性来声明一个更大的heap空间,之后可以通过getLargeMemoryClass()来获取到一个更大的heap大小。但这不是该值得提倡的方法,因为使用额外的内存会影响系统整体的用户体验,并且会使得GC的运行时间更长。在任务切换时,系统的性能会变得大打折扣。

而且, large heap并不一定能够获取到更大的heap。在某些有严格限制的机器上,large heap的大小和通常的heap size是一样的。因此即使你申请了large heap,你还是应该通过执行getMemoryClass()来检查实际获取到的heap大小。

  1. 创建多进程

内存泄漏

对象由于编码错误或系统原因,仍然存在着对其直接或间接的引用,导致系统无法进行回收。
内存泄漏引发的常见问题有:

  • 应用卡顿,响应速度慢(内存占用高时JVM虚拟机会频繁触发GC);
  • 应用被从后台进程处理为空进程;
  • 应用莫名崩溃(引起OOM);

常见泄漏类型

单例模式导致的内存泄漏

使用单例持有Context,需要记得释放,或使用全局上下文。

静态变量导致的内存泄漏

除了避免显示地使用静态变量引用拥有自己生命周期的对象外,也需要注意一些隐式的使用,如下:

private static Drawable sBackground;
@Override
protected void onCreate(Bundle state) {
    super.onCreate(state);
    TextView label = new TextView(this);
    label.setText("Leaks are bad");
    if (sBackground == null) { 
        sBackground = getDrawable(R.drawable.large_bitmap);
    }
    label.setBackgroundDrawable(sBackground);
    setContentView(label);
}

sBackground是一个静态的变量,我们虽然没有显式地保存Context的引用,但是,当Drawable与View连接之后,Drawable就将View设置为一个回调,由于View中是包含Context的引用的,所以,实际上我们依然保存了Context的引用。这个引用链如下:Drawable->TextView->Context
所以,最终该Context也没有得到释放,发生了内存泄露。

解决方案
  • 尽量避免静态变量引用资源耗费过多的对象,如Context,同时注意对静态对象的释放。
  • Context尽量使用ApplicationContext。
  • 使用W
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值