2. 存储硬件基础
Android 设备的存储性能,首先由硬件介质决定。应用层的数据库、文件读写、日志落盘、媒体缓存,最终都要经过文件系统、块层、驱动,落到 eMMC、UFS、NVMe 或 SD 卡等物理介质上。理解这些介质的读写原理与性能边界,是后续 IO 调优的前提:如果瓶颈在硬件本身,再多的软件优化也只能逼近其上限,而无法突破。
一、核心原理:从 NAND 闪存到块设备
无论 eMMC、UFS 还是 NVMe SSD,其存储核心都是 NAND Flash。NAND 的物理特性决定了三条铁律:读以页为单位、写以页为单位、擦除以块为单位。典型 NAND 的页大小为 4KB~16KB,块由数百个页组成。写入时只能把 1 写成 0,要把 0 变回 1 必须先擦除整块。因此,当需要修改一个已写入的页时,控制器不能原地覆盖,只能把新数据写到新的空闲页,并把旧页标记为无效,这个过程称为写放大。
为了掩盖 NAND 的擦写限制,控制器内部运行 FTL(Flash Translation Layer),通过逻辑地址到物理地址的映射,把块设备接口暴露给上层。同时,磨损均衡、垃圾回收(GC)、坏块管理都在控制器内完成。垃圾回收会在后台搬运有效页、擦除整块,这会与前台 IO 争抢带宽,造成偶发的延迟尖峰——这正是很多“卡顿”问题的硬件根源。
二、四类介质的结构与特性对比
eMMC 是“NAND + 控制器”封装为一颗 BGA 芯片,通过并行总线与 SoC 相连,协议相对简单,成本低,常见于入门机型。UFS 在 eMMC 基础上引入串行差分链路与命令队列(Command Queue),支持全双工读写,即读写可以同时进行,并支持 HS-GEAR 速率等级,性能大幅提升,是当前中高端 Android 设备的主流。NVMe 则是面向 PCIe 总线的协议,拥有极深的队列深度与极低协议开销,在手机端多以 UFS 卡或板载形式出现,在平板、车机、笔记本形态中更常见。SD 卡是可插拔介质,通过 SDIO 或 UHS 接口接入,速度等级参差,且热插拔、供电与协议开销都带来额外不确定性。
三、性能指标:看懂规格书与实测数据
评估存储介质时,不能只看“容量”和“最大顺序读”。真正影响 Android 体验的指标包括:
- 顺序读写带宽:影响大文件拷贝、视频录制、应用安装解压。
- 随机读写 IOPS:4KB 随机读写在数据库、SharedPreferences、日志场景中占主导,直接决定应用启动与列表滑动流畅度。
- 访问延迟:单次 IO 的响应时间,UFS 与 NVMe 的队列机制能显著降低高并发下的平均延迟。
- 队列深度与并发:UFS 的 CQ、NVMe 的多队列,允许更多请求并行,提升吞吐。
- 耐久度(TBW/DWPD):写入寿命,影响长期使用后的掉速与可靠性。
- 热稳定性:高负载下控制器降频,性能会明显回落。
| 介质 | 接口/协议 | 典型顺序读 | 典型随机读 | 并发能力 | 典型场景 |
|---|---|---|---|---|---|
| eMMC 5.1 | 并行 · 半双工 | 约 250~400MB/s | 约 5K~15K IOPS | 弱 | 入门手机、电视盒子 |
| UFS 2.2 | 串行 · 全双工 · CQ | 约 800MB/s~1GB/s | 约 30K~60K IOPS | 中 | 中端手机 |
| UFS 3.1/4.0 | 串行 · 全双工 · CQ | 约 1.8~4GB/s | 约 80K~200K IOPS | 强 | 旗舰手机、平板 |
| NVMe SSD | PCIe · 多队列 | 约 3~7GB/s | 约 200K~1M IOPS | 很强 | 车机、笔电、服务器 |
| SD UHS-I | SDIO · 半双工 | 约 90~104MB/s | 约 1K~3K IOPS | 弱 | 外置扩展、相机 |
四、方法流程:如何定位与验证存储瓶颈
在真机调优时,建议按以下流程确认硬件是否成为瓶颈:
- 先用
fio或AndroBench做基线测试,分别测顺序读写与 4KB 随机读写。 - 用
iostat、blktrace观察 IO 队列深度、await 延迟与 %util。 - 对比应用实际 IO 模式:是大量小随机写,还是大块顺序读。
- 若随机写 IOPS 已接近介质上限,应优先改软件策略(批量写、合并、异步),而非继续压硬件。
# 4KB 随机写测试示例
fio --name=randwrite --ioengine=libaio --direct=1 \
--rw=randwrite --bs=4k --size=256M --numjobs=4 \
--iodepth=32 --runtime=30 --group_reporting
# 查看块设备 IO 统计
iostat -x 1
五、案例与场景:同一份代码,不同介质差异巨大
某日志组件在旗舰 UFS 3.1 机型上每秒写入 2000 条小记录毫无压力,但在 eMMC 5.1 的入门机上出现明显卡顿。原因在于:每条日志都是一次 4KB 随机写,eMMC 的随机写 IOPS 只有 UFS 的十分之一左右,且半双工无法读写并行,GC 一触发,前台写入延迟从毫秒级跳到几十毫秒。优化手段不是换硬件,而是把日志改为内存缓冲 + 批量顺序落盘,把随机写转成顺序写,卡顿随即消失。
六、常见误区与复盘
- 只看顺序读速度:顺序读高不代表随机写好,而 Android 日常 IO 以随机小写为主。
- 把 SD 卡当内部存储用:SD 卡随机性能差、热插拔风险高,不适合数据库与频繁写日志。
- 忽视 GC 与热降速:长时间高负载后性能回落是正常现象,测试要覆盖持续写入场景。
- 用错测试工具:不带
direct=1的测试会被页缓存掩盖真实介质性能。