一、系统裁剪概述:为什么要做系统裁剪?
说实话,我做了十几年系统优化,见过太多「大炮打蚊子」的案例。
一个嵌入式设备,跑着完整的 Linux 发行版。开机两分钟,内存吃掉大半。你说它功能全吗?全。但真正用到的,可能不到 20%。
这就是我们要做系统裁剪的原因。
1.1 性能瓶颈到底在哪?
先别急着动手。你得先搞清楚,系统慢在哪。
我个人习惯,拿到一个系统,先看三个地方:
- CPU 空转率 —— 是不是大量时间花在调度无关进程上?
- 内存占用分布 —— 谁在吃内存?内核?驱动?还是用户态服务?
- 磁盘 I/O 瓶颈 —— 是不是频繁读写日志、临时文件?
我在项目中遇到过一台工业网关,启动要 45 秒。查了半天,发现光 udev 规则加载就占了 12 秒。裁剪掉不需要的设备规则,启动时间直接降到 18 秒。
核心观点: 性能瓶颈往往不是硬件不够强,而是软件太臃肿。裁剪的本质,是「去掉你不需要的,让需要的跑得更快」。
1.2 裁剪能带来什么收益?
说白了,就三个字:快、小、稳。
| 维度 | 裁剪前 | 裁剪后 | 典型提升 |
|---|---|---|---|
| 启动时间 | 45s | 12s | 73% |
| 内存占用 | 128MB | 48MB | 62% |
| 存储空间 | 512MB | 128MB | 75% |
| 系统响应 | 有卡顿 | 流畅 | 明显改善 |
你想想看,一个 128MB Flash 的设备,原来装完系统只剩 20MB。裁剪后,还能剩 100MB 给应用。这差距,不是一点点。
1.3 裁剪的核心原则
嗯,这里要注意。裁剪不是乱砍。我见过有人把 libc 都裁了,结果程序跑不起来。这就过头了。
我总结了四条原则,你可以记一下:
- 最小化原则 —— 只保留系统运行必需的最小集合。多一个进程都不要。
- 模块化原则 —— 功能按模块拆分,按需加载。用不到的模块,编译时就去掉。
- 可追溯原则 —— 每次裁剪都要记录。我曾经裁掉一个「看起来没用」的驱动,结果现场设备连不上网。查了两天才找到原因。
- 测试优先原则 —— 裁剪完必须做功能测试和压力测试。别让裁剪引入新 bug。
避坑指南: 我曾经在裁剪内核时,把 SCSI 支持整个去掉了。结果系统启动到一半就 panic。后来才发现,虽然设备用的是 SATA,但内核内部依赖 SCSI 层做磁盘管理。所以,裁剪前一定要搞清楚依赖关系。
1.4 裁剪的层次结构
系统裁剪不是一锤子买卖。它分几个层面,每个层面都有不同的侧重点。
下面这张图,是我自己画的一个裁剪层次结构。你可以对照着看:
从这张图你能看出来,裁剪是有顺序的。我个人建议,先从应用层下手。因为应用层改动风险最小,收益也最直观。
比如,一个设备只需要做数据采集,那 Web 服务器、SSH 服务、打印服务,统统可以去掉。这一刀下去,内存占用能降 30% 以上。
1.5 什么时候不该裁剪?
说了这么多裁剪的好处,我也得泼点冷水。
有些场景,真的不适合做裁剪:
- 通用型产品 —— 你不知道用户会怎么用。裁剪过度,反而限制用户。
- 快速原型阶段 —— 先跑起来再说。优化是后面的事。
- 维护成本敏感 —— 裁剪后的系统,维护起来更麻烦。每次升级都要重新裁剪。
我的建议: 如果你做的是专用嵌入式设备,比如路由器、工控机、IoT 终端,那裁剪是必修课。但如果你做的是通用服务器,那还是保持完整系统更稳妥。
1.6 裁剪前的准备工作
动手之前,先把这几件事做了:
- 建立基线 —— 记录当前系统的 CPU、内存、磁盘、启动时间等指标。
- 分析依赖 —— 用 ldd、readelf、systemd-analyze 等工具,搞清楚谁依赖谁。
- 制定目标 —— 明确你要达到什么效果。比如「启动时间 < 10s」「内存占用 < 64MB」。
- 准备回退方案 —— 裁剪失败了,能快速恢复。我一般会保留一份完整的系统镜像。
好了,这一章的内容就这些。记住一句话:裁剪不是目的,让系统跑得更快才是。