WHS GIS Engineer

Android 性能优化

2018-08-15
WHS

每个应用程序都需要内存作为执行其工作的资源。为了确保Android中的每个应用程序都有足够的内存,Android系统需要有效地管理内存分配。当内存不足时,Android运行时会触发垃圾收集(GC)。GC的目的是通过清理不再有用的对象来回收内存。简而言之,为用户提供服务的所有内容都应保存在内存中,其他所有内容都将从内存中消失以释放资源。 但是,如果以不良方式编写代码,从可访问对象以某种方式引用未使用的对象,GC会将未使用的对象标记为有用对象,因此无法删除它们。这称为内存泄漏。

什么是内存泄漏

每个应用程序都需要内存作为执行其工作的资源。为了确保Android中的每个应用程序都有足够的内存,Android系统需要有效地管理内存分配。当内存不足时,Android运行时会触发垃圾收集(GC)。GC的目的是通过清理不再有用的对象来回收内存。简而言之,为用户提供服务的所有内容都应保存在内存中,其他所有内容都将从内存中消失以释放资源。 但是,如果以不良方式编写代码,从可访问对象以某种方式引用未使用的对象,GC会将未使用的对象标记为有用对象,因此无法删除它们。这称为内存泄漏。

Java中有四种GC根:

  • 局部变量由一个线程堆栈保持活动状态。这不是真实对象虚拟参考,因此不可见。对于所有意图和目的,局部变量是GC根。

  • 活动Java线程始终被视为活动对象,因此是GC根。这对于线程局部变量尤为重要。

  • 静态变量由其类引用。这一事实使它们成为事实上的GC根源。类本身可以被垃圾收集,这将删除所有引用的静态变量。当我们一般使用应用程序服务器,OSGi容器或类加载器时,这一点特别重要。我们将在“问题模式”部分讨论相关问题。

  • JNI引用是本机代码作为JNI调用的一部分创建的Java对象。这样创建的对象是专门处理的,因为JVM不知道它是否被本机代码引用。这些对象代表了一种非常特殊的GC根形式,我们将在下面的“问题模式”部分中详细介绍。

为什么内存泄漏不好

  • 界面卡顿

  • ANR

    1. 在5秒内无响应输入事件(如按键或屏幕触摸事件)
    2. BroadcastReceiver尚未在10秒内完成执行。
    3. Service在特定的时间(20s)内无法处理完成。
  • OOM->崩溃

  • 在QA/测试中很难找到内存泄漏问题。它们难以复制。崩溃报告通常很难推理,因为它可以在Android系统拒绝内存分配的任何时间发生。

如何识别

  • LeakCanary工具

它会为您的应用中的活动创建弱引用。(您也可以通过向任何其他对象添加监视来自定义它。)然后检查GC之后是否清除了引用。如果没有,它会将堆转储到.hprof文件中并进行分析以确认是否存在泄漏。如果有,则显示通知,并在单独的应用程序中显示泄漏发生的参考树。

常见的内存泄漏的原因

  • Leak activity to a static reference
  • Leak activity to a worker thread
  • Leak thread itself

ANR问题

  • 导出 traces.txt 文件

通过adb导出 data/anr/traces.txt

如何避免ANR

不要在主线程(UI线程)里面做繁重的操作.

性能优化指标

  • 启动时间
  • 界面切换是否卡顿
  • 过度绘制

参考

Memory Leak Patterns in Android

Java Memory Management

Android启动加速优化


Similar Posts

Comments