TypeScript
# Chromebox3(Reef / i7-8550U / 8G)内存化与最小化 eMMC 写入优化文档
> 整理日期:2026-10-14 | 适用设备:Chromebox3 Reef | 固件:MrChromebox-4.20.0(保持不动)
>
> 目标:**尽量让运行时读写全部落在内存,最小化 eMMC 闪存写入**;已禁用磁盘 swap.img,8G 内存搭配 zram 做 OOM 兜底。
---
## 1. 设备与环境
| 项目 | 值 |
|---|---|
| 设备型号 | Chromebox3(Reef 板型) |
| CPU | Intel i7-8550U(4 核 8 线程) |
| 内存 | 8GB(内核可见约 7.9GB,`MemTotal` 约 7900MB) |
| 存储 | eMMC 闪存(`/dev/sda`,根分区 `/dev/sda2` ext4) |
| 固件 | MrChromebox-4.20.0(不改动 UEFI 设置) |
| 系统 | Ubuntu 24.04/26.04 系,systemd + GNOME |
| 已知硬件问题 | s2idle(现代待机)挂起后冷重启,`[s2idle] deep` 中实际使用 s2idle |
### 硬件特性与优化原则
- CPU 性能足够(i7-8550U),可承受 lz4 压缩负载,`ALGO=lz4` 兼顾速度与 CPU 占用。
- eMMC 闪存写寿命有限、写带宽低 → 一切可放内存的运行数据都放内存。
- 物理内存 8G 不算宽裕 → 必须给 GNOME 桌面、浏览器、内核缓存预留,zram 百分比不超过 45%。
- 无磁盘 swap → 内存耗尽只能 OOM 杀进程,不能休眠(hibernate 完全不可用)。
---
## 2. 优化目标与关键取舍
### 目标
1. 日志、临时文件、交换分区全部走内存(tmpfs / zram)。
2. 关闭/屏蔽一切不必要的磁盘写路径(atime、RTC 频繁刷写、睡眠挂起)。
3. eMMC 只承担:用户真正保存的文件、ext4 元数据与日志(保留,保证断电安全)。
### 关键取舍
| 取舍点 | 结果 |
|---|---|
| 日志放内存 | 重启后历史日志全部丢失;故障必须在发生时当场抓日志 |
| /var/tmp 放内存 | 依赖跨重启临时文件的软件可能丢数据 |
| 屏蔽全部睡眠 | 机器不能挂起待机,只能持续运行或关机 |
| 无磁盘 swap | zram 打满后直接 OOM 杀进程,无兜底 |
| ext4 journal | **必须保持开启**,禁止 `journal=off`,保障断电文件系统安全 |
---
## 3. 优化项总览
| # | 优化项 | 实现方式 | 状态 |
|---|---|---|---|
| 1 | journald 日志入内存 | `/etc/systemd/journald.conf.d/volatile.conf` drop-in | ✅ 生效 |
| 2 | sysctl 内核调优 | `/etc/sysctl.d/99-mem-only.conf` | ✅ 生效 |
| 3 | zram-tools(无磁盘 swap) | `/etc/default/zramswap`(lz4 / 45%) | ⚠️ 大小待最终确认 |
| 4 | `/var/tmp` 挂载 tmpfs | `/etc/fstab` 追加一行 | ✅ 生效 |
| 5 | 根分区 noatime | `/etc/fstab` 根分区挂载参数 | ✅ 生效 |
| 6 | 屏蔽睡眠单元 | `systemctl mask` 4 个 target | ✅ 生效 |
| 7 | 屏蔽 timesyncd watchdog | `systemctl mask systemd-timesyncd-watchdog.service` | ✅ 生效 |
| 8 | fstrim 保持 weekly | 默认定时器,不改动 | ✅ 默认 |
| 9 | 浏览器缓存指向内存 | Chromium/Firefox 缓存目录改 `/tmp` | ○ 可选,未执行 |
---
## 4. 详细配置与命令
### 4.1 journald 系统日志放入内存(volatile)
配置文件:`/etc/systemd/journald.conf.d/volatile.conf`
```ini
[Journal]
Storage=volatile
RuntimeMaxUse=64M
RuntimeMaxFileSize=16M
RateLimitIntervalSec=30s
RateLimitBurst=200
```
执行:
```bash
sudo mkdir -p /etc/systemd/journald.conf.d
sudo nano /etc/systemd/journald.conf.d/volatile.conf
# 粘贴上述内容,保存退出
# 删除磁盘日志目录,重启服务
sudo rm -rf /var/log/journal
sudo systemctl restart systemd-journald
```
效果:日志全部写入 `/run/log/journal`(tmpfs 内存),不再写 `/var/log/journal`(eMMC)。
验证:`journalctl --disk-usage` 显示的内存占用约 8M。
> 使用 drop-in 片段而非修改主配置,系统升级不会冲掉自定义配置。
### 4.2 sysctl 内核调优(延缓刷盘、压低 swap 触发)
配置文件:`/etc/sysctl.d/99-mem-only.conf`
```ini
# zram,无磁盘swap|Chromebox3 i7-8550U 8G
vm.swappiness=8
vm.vfs_cache_pressure=40
# 脏页:尽量攒更多在内存,减少频繁小刷盘
vm.dirty_background_ratio=8
vm.dirty_ratio=16
# zram优化:减少连续大页swap
vm.page-cluster=0
```
执行:
```bash
sudo nano /etc/sysctl.d/99-mem-only.conf
# 粘贴上述内容,保存退出
sudo sysctl --system
```
验证:
```bash
sysctl vm.swappiness vm.vfs_cache_pressure vm.dirty_background_ratio vm.dirty_ratio vm.page-cluster
```
**踩坑记录(重要)**:目录下曾同时存在 `999-mem-only.conf`(`vm.swappiness=10`),按字典序后加载覆盖了 99 号文件的 8,导致 swappiness=10。**已删除 999 号文件,只保留一份 99-mem-only.conf**。此外 zramswap 服务启动时会动态改写 swappiness,需用 `SET_SWAPPINESS=0` 关闭其接管(见 4.3)。
### 4.3 zram-tools(lz4 内存压缩 swap,无磁盘 swap)
先彻底清理旧的 systemd-zram-generator(防止两套 zram 冲突):
```bash
# 1. 清理旧 systemd-zram-generator
sudo swapoff /dev/zram0 2>/dev/null || true
sudo systemctl stop systemd-zram-setup@zram0.service 2>/dev/null || true
sudo rm -f /etc/systemd/zram-generator.conf
sudo apt remove systemd-zram-generator -y
sudo systemctl daemon-reload
# 2. 安装 zram-tools
sudo apt update
sudo apt install zram-tools
```
配置文件:`/etc/default/zramswap`
```ini
ALGO=lz4
PERCENT=45
#SIZE=512
PRIORITY=100
SET_SWAPPINESS=0
```
> - `ALGO=lz4`:速度优先,i7-8550U 可承受;想更高压缩率可改 `zstd`。
> - `PERCENT=45`:8G 内存取 45% ≈ 3.6G zram;不要超过 45%,给桌面留物理内存。
> - 若 PERCENT 不生效(表现为大小停在 40% 的 3.2G),改用固定大小:`#PERCENT=45` 注释掉,写 `SIZE=3584`(MiB,≈3.5G,适配内核实际可见 7.9G 内存)。
> - `SET_SWAPPINESS=0`:禁止 zramswap 服务自动改 `vm.swappiness`,完全交给 4.2 的 sysctl 管控。
执行与彻底重建(restart 不一定会重新计算大小,必须卸载内核模块):
```bash
sudo systemctl restart zramswap
# 若大小未变,彻底重建:
sudo swapoff /dev/zram0
sudo systemctl stop zramswap
sudo modprobe -r zram
sudo systemctl start zramswap
```
验证:
```bash
zramctl
swapon --show
```
期望:`/dev/zram0` lz4,DISKSIZE ≈ 3.5G(3584M)或 3.6G,PRIO=100,**只有 zram0,绝无 /swap.img**。
### 4.4 `/var/tmp` 挂载为 tmpfs 内存(1G)
编辑 `/etc/fstab`,末尾追加一行:
```
tmpfs /var/tmp tmpfs defaults,noatime,mode=1777,size=1G 0 0
```
执行:
```bash
sudo nano /etc/fstab
# 追加上述行,保存退出
sudo mount -o remount /var/tmp
```
验证:
```bash
mount | grep /var/tmp
# tmpfs on /var/tmp type tmpfs (rw,noatime,size=1048576k,inode64)
```
> `/tmp` 系统默认已是 tmpfs;`/var/tmp` 默认落盘,改内存后重启清空,跨重启临时文件会丢失。
### 4.5 根分区开启 noatime
编辑 `/etc/fstab`,根分区挂载参数增加 `noatime`:
```
UUID=xxxx-xxxx / ext4 noatime,errors=remount-ro 0 1
```
执行:
```bash
sudo nano /etc/fstab
sudo mount -o remount /
```
验证:
```bash
mount | grep ' / '
# /dev/sda2 on / type ext4 (rw,noatime,errors=remount-ro)
```
> 只加 noatime,不要动其他参数;**不要关闭 ext4 日志**(断电保护)。
### 4.6 屏蔽睡眠相关单元(规避 s2idle 冷重启 bug)
```bash
sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target
```
验证:
```bash
systemctl status suspend.target --no-pager
# Loaded: masked
cat /sys/power/mem_sleep
# [s2idle] deep ------ 支持 s2idle,但已被屏蔽不启用
```
> Chromebox3 的 s2idle 挂起会冷重启,屏蔽后系统菜单"挂起"完全失效;机器只能持续运行或关机。
### 4.7 屏蔽 systemd-timesyncd watchdog(减少 RTC 频繁刷写)
```bash
sudo systemctl mask systemd-timesyncd-watchdog.service
```
> 时间同步功能本身仍正常工作,只是关闭其频繁刷写 RTC 的写盘动作。
### 4.8 fstrim 定时器保持 weekly
```bash
systemctl list-timers | grep fstrim
```
保持默认一周一次 TRIM,**不要改成 daily**,频繁执行反而增加 eMMC 负载。
### 4.9 浏览器缓存放到内存(可选)
- Chromium/Chrome:启动参数加 `--disk-cache-dir=/tmp/chrome-cache`
- Firefox:设置 → 隐私与安全 → 网络设置 → 缓存位置改为 `/tmp/firefox-cache`,重启浏览器。
---
## 5. 当前状态核对(2026-10-14 实测)
| 检查项 | 实测输出 | 判定 |
|---|---|---|
| journald 存储 | `Archived and active journals take up 8M`(无 `/var/log/journal`) | ✅ volatile 生效,占用为内存 |
| zram | `/dev/zram0 lz4 3.2G PRIO=100`,无磁盘 swap | ⚠️ 大小待重建验证为 3.5G(固定 SIZE) |
| vm.swappiness | `8` | ✅ |
| vm.vfs_cache_pressure | `40` | ✅ |
| vm.dirty_background_ratio / dirty_ratio | `8` / `16` | ✅ |
| vm.page-cluster | `0` | ✅ |
| 根分区 | `ext4 (rw,noatime,errors=remount-ro)` | ✅ |
| /tmp | tmpfs | ✅ |
| /var/tmp | tmpfs `size=1048576k`(1G) | ✅ |
| suspend.target | `masked`,`[s2idle] deep` | ✅ 睡眠已屏蔽 |
**待办**:zram 大小改为固定 `SIZE=3584` 后整机重启,确认开机后 DISKSIZE ≈ 3.5G、swappiness=8。
---
## 6. 校验脚本 `check_mem_opt.sh`
```bash
#!/bin/bash
echo "==== journald ===="
systemctl show -p Storage systemd-journald
journalctl --disk-usage
echo -e "\n==== zram ===="
zramctl
swapon --show
echo -e "\n==== sysctl vm ===="
sysctl vm.swappiness vm.vfs_cache_pressure vm.dirty_background_ratio vm.dirty_ratio vm.page-cluster
echo -e "\n==== mount ===="
mount | grep -E ' / |/var/tmp|/tmp'
echo -e "\n==== masked sleep units ===="
systemctl is-masked sleep.target suspend.target hibernate.target hybrid-sleep.target
echo -e "\n==== fstrim timer ===="
systemctl list-timers | grep fstrim
```
```bash
chmod +x check_mem_opt.sh
./check_mem_opt.sh
```
---
## 7. 风险与注意事项
1. **无磁盘 swap 兜底**:zram 打满 → OOM killer 直接杀进程,多开大量网页容易闪退。
2. **journal volatile**:崩溃重启后历史日志全部丢失,排错必须在故障当场抓日志。
3. **/var/tmp 在 tmpfs**:依赖跨重启保留临时文件的软件会丢失数据。
4. **睡眠全部屏蔽**:机器无法挂起待机,只能持续运行或关机;`hibernate` 完全不支持。
5. **ext4 日志保持开启**:禁止 `journal=off`,保障 eMMC 断电安全。
6. **不要执行 `systemctl hibernate`**:无磁盘 swap,休眠不可用。
7. 固件维持 MrChromebox-4.20.0 不动,不要改动 UEFI 设置。
---
## 8. 回滚方案(异常时一键恢复默认行为)
```bash
# 1. journald 恢复磁盘日志
sudo rm /etc/systemd/journald.conf.d/volatile.conf
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald
# 2. 恢复内核默认参数
sudo rm /etc/sysctl.d/99-mem-only.conf
sudo sysctl --system
# 3. 卸载 zram-tools(并恢复磁盘 swap.img 的启用)
sudo apt remove zram-tools -y
# 4. fstab 恢复:删除 /var/tmp 的 tmpfs 行、去掉根分区 noatime
sudo nano /etc/fstab # 手动编辑后保存
sudo mount -o remount /
sudo mount -o remount /var/tmp
# 5. 解除睡眠与 watchdog 屏蔽
sudo systemctl unmask sleep.target suspend.target hibernate.target hybrid-sleep.target systemd-timesyncd-watchdog.service
# 6. 按需恢复磁盘 swap:在 /etc/fstab 中恢复 /swap.img 条目并 swapon
```
---
## 9. 附录:常用日常运维命令
```bash
# zram 实时状态
zramctl
free -h
# swap 设备(应只有 /dev/zram0)
swapon --show
# 内存/磁盘占用总览
df -h / /tmp /var/tmp /run/log/journal
```