Android 内存缓存写入磁盘的机制和时间
Android 系统采用多层缓存机制来平衡性能和数据持久性,了解这些机制对于防止数据丢失至关重要。
一、核心写入机制
1. 页面缓存(Page Cache)机制
位置:Linux内核层
功能:所有磁盘I/O操作都经过页面缓存
特点:
写入操作默认先到页面缓存
由内核线程pdflush定期(通常30秒)将脏页写入磁盘
内存压力时会触发更频繁的写入
2. 文件系统层机制
ext4/f2fs特性:
默认数据模式data=ordered(先写数据后写元数据)
可配置为data=journal(日志模式,更安全但性能低)
同步点:
文件关闭时调用fsync()/sync()时
系统定时器触发时(通常5秒)
二、Android特有的写入行为
- SharedPreferences写入
方法 同步性 默认延迟 强制写入方式
apply() 异步 ≤100ms 无保证
commit() 同步 立即 调用后仍需等待fsync完成
- SQLite写入
默认模式(WAL日志):
写入先到WAL文件
检查点(checkpoint)时同步到主数据库(默认每2MB或事务提交时)
PRAGMA synchronous = FULL; // 最安全(默认)
PRAGMA synchronous = NORMAL;
PRAGMA synchronous = OFF; // 危险
三、关键时间参数
内核参数:
dirty_writeback_centisecs:控制pdflush运行频率(默认500,即5秒)
dirty_expire_centisecs:脏页最长存在时间(默认3000,即30秒)
Android调整:
# 查看当前值
cat /proc/sys/vm/dirty_expire_centisecs
# 临时修改(需root)
echo 1000 > /proc/sys/vm/dirty_writeback_centisecs
四、强制同步方法对比
image.png
性能影响测试:
- fsync()调用耗时:低速eMMC设备上可能达100-200ms
- 频繁调用会导致明显的性能下降
关键数据写入流程
// 1. 写入文件
FileOutputStream fos = new FileOutputStream(file);
fos.write(data);
// 2. 强制同步文件
fos.getFD().sync();
// 3. 确保目录条目更新
File dir = file.getParentFile();
FileOutputStream dirSync = new FileOutputStream(dir);
dirSync.getFD().sync();
dirSync.close();
// 4. 关闭文件
fos.close();
监控工具
# 查看待写入脏页数量
cat /proc/meminfo | grep Dirty
# 跟踪同步调用
strace -p <pid> -e trace=fsync,fdatasync,sync
理解这些机制后,开发者可以根据应用场景在性能和数据安全性之间做出合理权衡。