得力管家还是多此一举?聊聊 macOS 后台进程管理工具 App Tamer

15:39

AppTamer是St.ClairSoftware开发多年的一款菜单栏工具。它常驻后台、实时监控所有运行中的进程,主打以可视化的方式管控应用后台资源占用。通过AppTamer,用户既可以设定进程的CP ...


App Tamer 是 St. Clair Software 开发多年的一款菜单栏工具。它常驻后台、实时监控所有运行中的进程,主打以可视化的方式管控应用后台资源占用。通过 App Tamer,用户既可以设定进程的 CPU 占用上限,也可以指定线程占用的核心类型,还可以强制应用在切入后台时直接挂起。

我此前数次浅尝 App Tamer,但总觉得这个工具有点多此一举——macOS 自带的调度足够无感,偶尔用活动监视器定位问题即可,平时无须人工干预。直到最近,我的设备遇到了一些性能瓶颈,又正好发现 App Tamer 的 3.0 版正在公测,才算真正用了起来。下面,我就来聊聊重新捡起这款工具的动机、它的工作原理,以及在哪些场合可能值得一试。

开始使用的动机

作为一般原则,在操作系统自带的性能调度机制没有明显不足的情况下,没有必要寻求第三方工具的帮助。的确,macOS 自 10.9 起便引入了「App 小憩」(App Nap)机制,会在窗口完全不可见且不播放音频时,压低应用的调度优先级。

然而,App 小憩是一个相当「心慈手软」的机制,只在面对那些根据 macOS 原生规范开发的应用时有较好的效果,不足以应对目前复杂、臃肿的应用生态。根据 App 小憩 的豁免条件,只要应用持有任何系统资源(网络连接、定时器等),或在播放音频,就不会被置于小憩状态。

以浏览器为例,轮播的 banner 广告动画,定时轮询、抓取与刷新的社交媒体时间线,监听其他用户的操作并同步状态的在线文档,无不持续占用着系统资源,从而不能被 App 小憩机制所调节。类似地,许多使用 Electron 框架的套壳 web 应用也不听从 App 小憩的指挥。

此外,对于我这样的多显示器用户而言,同时显示的窗口变多了,也就意味着在系统看来处于「后台」的应用少了。这进一步限制了 App 小憩机制的调节空间。因此,当我给手头用了好几年的 M1 Pro MacBook Pro 外接了两块显示器后,明显感觉到就算开机放着什么都不做,CPU 也有明显的持续占用。

只有寥寥数个应用能进入小憩状态,不少还是自带应用。

既然系统的自动优化在这种场景下力有不逮,App Tamer 这样的第三方工具便有了用武之地。

App Tamer 的功能和原理

App Tamer 提供三种管控策略,可单独或组合施加于每个应用:

  1. 完全停止(stop this app completely):应用切入后台时挂起进程。效果最彻底,适合完全不需要后台活动的应用;
  2. 在效率核心上运行(run this app on the CPU’s efficiency cores):把应用线程限制在小核心上,应用仍能执行后台任务,只是降低了性能。对需要保持连接但不要求实时响应的应用(即时通讯、AI 客户端),这是侵入性最低的选项;
  3. 达占用率门槛后限速(slow down this app if it uses more than…):设定进程的最大 CPU 占用比例。适合必须持续运行、但不需要占满资源的系统进程,如索引服务、备份服务。

App Tamer 还内置了一些保护逻辑:检测到音频播放或文件下载时不会暂停对应应用,并定期唤醒被停止的应用以更新数据;也支持「闲置窗口超过一定时间即退出或隐藏」。

那么,这几种策略分别是如何实现的呢?

其中,第一项「完全停止」和第三项「达占用率门槛后限速」都是通过发出进程信号(signal)来实现的。signal 是类 Unix 系统中一种通知机制:内核或具有管理权限的进程可以使用系统调用 kill(2),向另一个进程「投递」一个 signal,打断其执行,并要求它作出反应。signal 有多种类型,常见的包括 SIGTERM(请求退出)、SIGKILL(强制终止)、SIGSTOP(挂起)、SIGCONT(恢复)等。

如果选择「完全停止」,当目标应用进入后台时,App Tamer 会向其进程发送一个 SIGSTOP。这个 signal 会使得内核冻结该进程的全部线程,但保留它在内存中的地址空间;换言之,在停止执行的同时保留数据。当切回该应用时,App Tamer 便会再向其进程发送一个 SIGCONT,解除其冻结状态。

而如果选择「达占用率门槛后限速」,App Tamer 会交替地向目标进程发送 SIGSTOPSIGCONT,令其在冻结与运行之间反复切换;只要调整这两个信号之间的间隔,就能间接控制目标进程的 CPU 占用率。例如,要将一个进程的 CPU 占用率限制在 10% 以内,只要让它在约 90% 的时间处于挂起状态即可。

另一方面,第二项策略「在效率核心上运行」则是通过调整应用的 QoS 优先级参数来实现的。

回顾一下,从第一代产品 M1 开始,Apple silicon 系列处理器就一直采用「大小核」设计。其中,M4 及更早的型号分为性能核心(P Core)和效率核心(E Core),如名称所表明,分别着重高性能和低能耗。从 M5 开始,苹果将性能核心更名为超级核心(S Core),将性能核心(P Core)重新定位为兼顾性能和能耗的居中类型,专供 Pro 和 Max 型号中使用。

尽管不同代际和型号的 Apple silicon 具有不同核心组合方式,但其调度方式是一致的,即 iOS 移植到 macOS 的 QoS(Quality of Service)机制。QoS 把线程划分为若干等级,获得 QoS 9(Background)及以下的线程被严格限制在较低性能的核心上,即便较高性能的核心完全空闲也不会迁移过去;获得更高 QoS 等级的线程则优先分配到较高性能的核心,仅在满载时,才会「溢出」到小核心。

因此,要调整线程的核心归属,实际上就是调整它的 QoS 等级。对此,macOS 提供了一个名为 setpriority(2) 的系统调用。如果通过 setpriority(2) 将一个进程的优先级设为 PRIO_DARWIN_BG,即可确保该进程在小核上运行。

(在使用 Intel 芯片的旧机型上,由于并无大小核区分,该选项会变为「以低优先级运行该应用」。)

配置建议

App Tamer 自带一套偏保守的预设:Adobe 旗下部分应用与内置的「预览」会被完全停止,其他多数应用则只在达占用率门槛后限速。以下是我根据自己的使用习惯,摸索出的一些额外设置建议:

会员专属文章,欢迎加入少数派会员。
优质内容
权益周边
会员社群
power+
评论区
全部评论0
成为少数派会员方可评论,立即加入。若已是少数派会员,点击登录
还没有评论,来发表第一个评论吧
全部评论
还没有评论,来发表第一个评论吧
成为少数派会员方可评论,立即加入。若已是少数派会员,点击登录
会员新功能
内容侧边栏
点击这里拉开侧边栏,即可查看会员内容列表,快速切换内容。