电脑卡卡卡,但你真的需要 SSD 吗?

不知从什么时候开始,SSD 渐渐成为解决电脑卡顿的第一解决方案。甚至关于 MacBook 与 Windows 笔记本的流畅度之争的核心,也是围绕是否标配 PCI-E 接口的 SSD。而且大家纷纷换上 SSD 之后,也确实感觉到了系统运行速度的质的变化。似乎大家都忘了,若干年前大家刚装好的 XP 系统,也能做到一分钟内开机,打开 Word 文档似乎也是看个过场动画就打开了。那么究竟是什么导致现在电脑对 SSD 这么饥渴的需求呢?

我们先来看一张截图:

2

这是二葱自己电脑的启动项的截图,可能很多人都在各种系统优化技巧里读到过,禁用其中的一部分启动项可以提升系统的启动速度。然而事实是,经常见到安装了国产流氓软件套装的电脑,即便是把这些启动项都禁掉(所谓一键优化),依然需要花费数分钟的时间才能进入系统,好容易到了桌面了,还要失去响应好长时间。讽刺的是,二葱把这些启动项都打开,依然可以做到在一个微信小视频的时间内开机进入桌面。

要想弄清楚这个问题,必须先弄清楚 Windows 的启动流程。

3

  1. MBR 阶段(16 位实模式):BIOS 在完成通电自检后,将控制权移交给位于硬盘前 63 个扇区的 MBR(Master Boot Record),MBR 将自己的镜像加载到内存,然后执行对分区表的搜索,然后将控制权转移给第一个活动分区的 PBR(Partition Boot Record);
  2. PBR 阶段(16 位实模式):PBR 是因操作系统而异的分区引导记录,它将自身加载到内存并加载基本的磁盘驱动,通过 BIOS INT 中断的方式查找此分区上的引导文件,也就是我们的 Bootmgr,并将其加载到内存;
  3. Bootmgr 阶段(16 位实模式和 32 位无分页内存):读取 BCD 信息,显示启动菜单,如果安装有多个版本的 Windows 引导记录,能在这里选择要启动的系统,或者执行内存测试等操作,在选定操作系统后,将 Windows BootLoader——Winload.exe 加载到内存;
  4. Winload.exe 阶段(32 位或 64 位 保护模式,有内存分页):加载 Windows 内核 Ntoskrnl.exe 和它的依赖项 Kdcom.dll(Kernel Debugger),Ci.dll,Clfs.sys,Pshed.dll,HAL.dll(硬件抽象层,其实就是主板驱动),并将注册表中 HKLMSYSTEM 子键内容加载到内存,如果检测到页面文件 Hiberfil.sys 则启动 Winresume.exe 恢复休眠文件;
  5. Ntoskrnl.exe 阶段(保护模式):初始化 Windows 执行体并一一加载注册在 HKLMSYSTEMCurrentControlSetServices 下标记为 System 的系统驱动程序,运行会话管理器 smss.exe,准备运行 native code 所需的环境;
  6. Smss.exe 阶段(Native 程序):初始化环境变量和 Windows 图形子系统(Win32k.sys),初始化 Windows API(csrss.exe)和 Windows 初始化进程(WinInit.exe)和登陆进程(WinLogon.exe);
  7. WinInit.exe 阶段(Windows 程序):初始化服务管理器(SCM),本地安全鉴定进程(LSASS)和本地会话管理器(LSM),初始化剩余的注册表中的启动项内容,以用户态运行启动项任务;
  8. Winlogon.exe 阶段:显示登陆画面,处理与用户登录相关的安全鉴定任务;
  9. Services.exe 阶段:完成加载在 HKLMSYSTEMCurrentControlSetServices 下标记为 AutoStart 的驱动程序和 Windows 服务;
  10. Explorer.exe 阶段:在创建 Windows Shell(Explorer.exe)时,初始化桌面窗口管理器(DWM)进程,Explorer.exe 加载自身和相关启动项。

自此 Windows 的启动流程才算基本结束。下图是二葱在虚拟机里安装的基本纯净的 Win 7 系统完成启动后的所有进程:

4

图中可以看出进程的父子关系,其中粉色标注的是系统服务,淡蓝色的是用户进程。之前提到,以高完整性级别运行某个程序,需要 UAC 提权,而且以管理员账户是不能以 SYSTEM 的身份创建进程的。那么图中以 SYSTEM 运行的电脑管家、甚至是 Bing 输入法的更新程序,还有以 High 级别运行的子进程是如何创建的呢?

5

答案就藏在 HKLMSYSTEMCurrentControlSetServices 中,读到这里大家不妨运行 regedit 亲自查看一下自己电脑里的注册表项,这是大部分在启动时加载或延时加载的 Windows 服务和相关驱动。刚才文章开头从任务管理器里看到的启动项,把它们都加起来,应该都没有这个子键下的启动项要多,甚至都不在一个数量级上。每个子键下,Start 的值都表示着这个启动项的触发时间:

  • 0:由 BootLoader 加载,比系统内核启动的时间还要早,标为 0 的多是底层 ATA 驱动;
  • 1:由 Ntoskrnl 加载,比如各类常规硬件驱动、过滤型驱动,还有各路安全卫士的程序本体、QQ 的窗体保护驱动等;
  • 2:由 WinInit 加载或特定事件触发,在基本的 GDI 图形初始化完成后才加载的程序,如果装的程序多的话,也会占用不少启动时间;
  • 3:手动加载;
  • 4:该项被禁用。

其中 Start 值为 0 和 1 的启动项,是以高权限加载的,即上图中标注为粉色的进程。

现在事实的真相已经浮出水面了,如果你觉得自己的电脑启动时间过长——甚至 SSD 也没有带来改善的话,可以去看一下注册表的 HKLMSYSTEMCurrentControlSetServices 这里,是不是有上百个加载项。二葱在舍友的电脑上试了下,发现早就被他卸载的 xx 日历、xx 视频、xx 助手各类软件一个不少,一共五百多项,这样的电脑恐怕连 SSD 都无法拯救吧。

(如果需要对这里面的启动项进行删减,请一定一定不要直接删除所怀疑的子键,就不说三遍了,记住如果想禁用一个 Services 里的启动项,先手动把 Start 的值改为“3”或“4”,如果重启之后使用一段时间确实不会产生负面影响的话,再考虑删掉这个子键。对于普通用户,更是不建议手动对注册表做任何改动,因为 HKEY_LOCAL_MACHINE 下的子键涉及系统全局配置,修改不善会造成整个系统的不稳定)

这还没完,在加载完驱动和服务之后,WinInit 还要继续加载这里的用户态启动项:

  • HKLMSOFTWAREMicrosoftWindowsCurrentVersionRunOnce
  • HKLMSOFTWAREMicrosoftWindowsCurrentVersionPoliciesExplorerRun
  • HKLMSOFTWAREMicrosoftWindowsCurrentVersionRun
  • HKCUSoftwareMicrosoftWindows NTCurrentVersionWindowsLoad
  • HKCUSoftwareMicrosoftWindows NTCurrentVersionWindowsRun
  • HKCUSoftwareMicrosoftWindowsCurrentVersionRun
  • HKCUSoftwareMicrosoftWindowsCurrentVersionRunOnce
  • %ALLUSERSPROFILE%Start MenuProgramsStartup
  • %USERPROFILE%Start MenuProgramsStartup

对于详细的 Windows 启动流程大家可以参考:The Birth of Windows Desktop ,更加详细的信息可以查阅 Windows Internals Book 一书的第 13 章:启动和关机。

这里向大家推荐一个检测系统启动项的工具:Autoruns,在 Sysinternals Suite 中可以找到。它能检测系统中存在的所有类型的启动项,包括由 WinInit 加载的用户启动项、由系统加载的驱动启动项,还有跟 Explorer.exe 相关的启动项(比如右键关联菜单等)。

通过取消勾选就能干掉启动项,甚至能离线检测其他硬盘上的操作系统——如果它们损坏不能启动的话——通过禁掉可疑驱动的方式修复系统。这货还能导出刚配置好系统时的启动项记录,并在以后随时与之比较,找出新增的启动项

6

通过“Description”和“Publisher”可以基本确定一个启动项的作用和发布者,如果在这里看到不希望被自动加载的条目,可以直接取消勾选。通常不建议大家直接通过注册表编辑器直接改动 HKLMSYSTEMCurrentControlSetServices 里面的内容,但如果大家对系统机制有所了解,可以通过 Autoruns 可以基本确定非必需的启动项,然后手动干掉它。

回想起来,之前面试被问到系统启动项都有哪些的时候,才知道自己的回答有多么幼稚。好在知之甚少不可怕,只要做到比昨天知道的更多就好。像这种经常被大家忽视的真相,就一定要让更多人知道。所以如果看完你觉得大彻大悟,原来自己被耍这么久,请不要忘记分享到朋友圈:)

最后再提一下 Windows 8 引入的快速启动功能,如下图所示,多数电脑都会默认开启这个选项:

7

打开了 “快速启动”的电脑,在关机时不会像以前那样依次结束进程然后关闭电源,而是在关闭了用户态的进程后,将 Session 0 的内核会话压缩到 Hibernate 文件中,在下次开机时并不会重新一一载入所有的设备驱动,而是直接将内核会话的休眠文件释放到内存,然后重新初始化它们。

8

据说这项技术最大能减少 70% 的启动时间。

另外,对于支持 UEFI 启动的电脑,通电自检时不再会像以前 BIOS 那样依次检测硬件设备的完好性,而是并行检测,也可以缩短 1~2 秒的启动时间。

9

所以说,如果你也时常向你的朋友表演开机,那么包括 SSD,UEFI、Windows 的快速启动、Prefetch 预读取这些技术都功不可没,虽然 SSD 能让系统运转如飞,但许多系统卡顿的原因可能并不是因为没有 SSD,而是因为用久了长出了许多流氓启动项。而且,别忘了向他们展示你的 HKLMSYSTEMCurrentControlSetServices,告诫他们合理安装国产软件,兴许号称帮你清理启动项的卫士本身,才是占据启动时间的大头:)

最后修改:2022 年 12 月 05 日
如果觉得我的文章对你有用,请随意赞赏