25、性能优化:启动时间优化、内存优化、GPU 渲染优化

车机系统的性能优化,说实话,跟手机端差别挺大的。手机卡了你可以重启,车机要是卡顿或者启动慢,用户可是会直接骂娘的。我在做某个量产项目时,就遇到过开机动画播完了,中控屏还黑着好几秒的情况。嗯,那段时间真是被测试和产品追着跑。

今天咱们就聚焦三个核心方向:启动时间内存GPU 渲染。这三块搞定了,车机的基本流畅度就有保障了。

Android Automotive 性能优化三大支柱 🚀 启动时间优化 • 减少 init 进程加载项 • 精简 Zygote 预加载类 • 推迟非关键服务启动 • 使用 PinnerService • 优化开机动画时长 • 并行化初始化任务 • 减少 dex2oat 耗时 • 使用系统级预编译 🧠 内存优化 • 减少内存泄漏 • 优化 Bitmap 内存 • 使用对象池模式 • 合理设置进程 Heap • 监控低内存杀进程 • 使用 Memory Profiler • 优化 Service 常驻 • 减少匿名共享内存 🎨 GPU 渲染优化 • 减少 Overdraw • 使用硬件加速 • 优化 View 层级 • 使用 SurfaceView • 减少 GPU 过度绘制 • 使用 Profile GPU • 优化动画帧率 • 使用 RenderThread

25.1 启动时间优化:从按下电源到界面可用

车机的启动时间,我一般把它拆成三个阶段:Bootloader → Kernel → Android Framework。每个阶段都有优化空间。

25.1.1 Bootloader 与 Kernel 阶段

这个阶段咱们能做的其实不多,但有几个点值得注意:

  • 减少 init.rc 中不必要的服务:很多厂商会把调试服务、logd 等默认开启。我建议只保留核心服务,其他的等系统启动后再按需启动。
  • 使用压缩的 Kernel:LZ4 压缩比 gzip 解压速度快很多。我在一个项目里把 Kernel 从 gzip 换成 LZ4,启动时间直接少了 200ms。
  • 优化设备树(DTB):不要加载用不到的硬件节点。你想想看,车机上又不需要摄像头,加载摄像头驱动干嘛?

25.1.2 Android Framework 阶段

这个阶段是优化的主战场。我个人习惯用 bootchart 来抓启动时序图,一眼就能看出哪里在卡脖子。

核心优化手段:

  • 精简 Zygote 预加载类:Zygote 启动时会预加载大量 Java 类。你可以通过 zygote --preload-classes 指定白名单,只加载车机真正需要的类。我见过一个项目预加载了 3000+ 个类,实际只用到了 800 个,白白浪费了 1.2 秒。
  • 推迟非关键服务:像蓝牙、Wi-Fi、OTA 更新这些服务,完全没必要在开机时启动。把它们放到 on boot 之后,或者用 start 命令手动触发。
  • 使用 PinnerService:把核心应用(如 Launcher、SystemUI)的代码和数据锁定在内存中,避免被页面置换。说白了就是「热数据常驻内存」。

💡 小技巧: 使用 adb shell am start -W 可以精确测量 Activity 的启动时间。重点关注 TotalTimeWaitTime 两个指标。

25.1.3 开机动画优化

开机动画其实是个「障眼法」。如果系统启动需要 8 秒,动画播 6 秒,用户就会觉得「嗯,挺快的」。但如果你动画播 10 秒,系统 8 秒就准备好了,用户反而会觉得「怎么黑屏了 2 秒?」

我曾经踩过一个坑:开机动画用了 4K 分辨率的 PNG 序列帧,每帧 8MB,结果解码成了瓶颈。后来换成 MP4 视频格式,启动时间直接砍半。

25.2 内存优化:别让车机变成「内存杀手」

车机的内存通常比手机小,而且不能像手机那样频繁杀后台。所以内存优化在 Automotive 上尤为重要。

25.2.1 内存泄漏排查

内存泄漏是性能劣化的头号元凶。我建议在开发阶段就开启 StrictMode,它能帮你抓到很多隐性的泄漏。

// 在 Application 中开启 StrictMode
if (BuildConfig.DEBUG) {
    StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
            .detectAll()
            .penaltyLog()
            .penaltyFlashScreen() // 泄漏时闪屏,很直观
            .build());
    StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
            .detectLeakedSqlLiteObjects()
            .detectLeakedClosableObjects()
            .detectActivityLeaks()
            .penaltyLog()
            .build());
}

⚠️ 注意: StrictMode 只适合 Debug 版本。Release 版本一定要关掉,否则会影响性能。

25.2.2 Bitmap 内存管理

Bitmap 是内存大户。车机上的地图、壁纸、图标动辄几 MB。我常用的优化手段:

  • 使用 inSampleSize 压缩:不要直接加载原图。根据 ImageView 的尺寸计算采样率。
  • 使用 RGB_565 代替 ARGB_8888:如果不需要透明度,RGB_565 能省一半内存。
  • 及时回收:在 Activity 的 onStop 或 onDestroy 中调用 bitmap.recycle()
  • 使用 Glide 或 Coil:这些库自带内存缓存和 LRU 策略,比自己手写强多了。

25.2.3 进程与 Service 管理

车机上有很多常驻 Service,比如导航、语音、音乐。如果每个 Service 都占一个进程,内存很快就爆了。

我建议:

  • 使用绑定 Service:多个组件共享同一个 Service 实例,减少进程数。
  • 合理设置 android:process:只有真正需要独立进程的服务才单独开进程。
  • 监控低内存杀进程:通过 /proc/meminfodumpsys meminfo 定期检查内存水位。

内存优化检查清单:

检查项工具/方法目标值
应用内存占用Memory Profiler< 200MB
Bitmap 内存dumpsys gfxinfo< 50MB
GC 频率Logcat 搜索 GC< 5次/分钟
低内存杀进程次数dumpsys activity processes0次/小时

25.3 GPU 渲染优化:让每一帧都丝滑

车机的 UI 交互要求很高。用户滑动地图、切换界面,如果掉帧,体验会非常糟糕。GPU 渲染优化的核心就是:减少 GPU 的工作量,让每一帧都在 16ms 内完成

25.3.1 减少 Overdraw

Overdraw 就是同一像素被多次绘制。说白了就是「画了又画」,浪费 GPU 性能。

我习惯用 开发者选项 → 调试 GPU 过度绘制 来检查。颜色越红,Overdraw 越严重。

  • 移除不必要的背景:如果父布局已经有背景,子布局就别再设背景了。
  • 使用 标签:减少布局层级,避免重复绘制。
  • 使用 ViewStub:延迟加载不常用的 View。

25.3.2 硬件加速与 RenderThread

Android 从 4.0 开始支持硬件加速。车机上一定要开启,否则所有绘制都会走 CPU,卡成 PPT。

// 在 AndroidManifest.xml 中开启硬件加速
<application android:hardwareAccelerated="true" ...>

开启硬件加速后,渲染工作会交给 RenderThread。它和 UI 线程并行工作,大大减少了掉帧的可能。你可以在 dumpsys gfxinfo 中看到 RenderThread 的耗时。

25.3.3 动画与帧率优化

车机上的动画很多:转场、旋转、缩放。我建议:

  • 使用属性动画:不要用 ViewAnimation,属性动画直接操作属性,不走重绘流程。
  • 使用 SurfaceView:对于地图、视频等高频刷新场景,SurfaceView 有独立的渲染表面,不会阻塞 UI 线程。
  • 控制帧率:不是所有动画都需要 60fps。比如一个简单的淡入淡出,30fps 就够用了。用 Choreographer 可以精确控制帧率。

💡 实战技巧: 使用 adb shell dumpsys gfxinfo <package> framestats 可以拿到每一帧的详细耗时。重点关注 DrawPrepareProcess 三个阶段。如果某个阶段超过 16ms,那就是瓶颈所在。

25.4 总结:性能优化是个系统工程

启动时间、内存、GPU 渲染,这三者其实是相互影响的。内存不足会导致 GC 频繁,GC 会卡住 UI 线程,UI 线程卡了就会掉帧。所以你不能只盯着一个点看。

我个人习惯的做法是:先抓大放小。用 bootchart 看启动时间,用 Memory Profiler 看内存泄漏,用 Profile GPU 看渲染瓶颈。找到最痛的点,先解决它。然后再循环迭代。

记住一句话:没有银弹。每个车机项目的硬件、系统版本、应用场景都不一样。你需要的是方法论,而不是死记硬背的优化技巧。


公众号:蓝海资料掘金营,微信deep3321