peopled 占满 Mac 的 CPU?在 macOS Tahoe 上,问题通常出在 Contacts 小组件
Tahoe 更新后 peopled 或 contactsd 卡在 70%–180% 的 CPU 占用,Mac 发烫、电量骤降?根源是一个读不到通话记录的 Contacts 小组件。这是真正管用的修复方法。
你的 Mac 什么都没做却在发烫,电量预估掉了一半。打开活动监视器,按 CPU 排序,排在最前面的是一个你从未听说过的进程——peopled——稳稳地停在 70% 或 80%,居高不下。也可能是 contactsd。在受影响最严重的机器上,甚至是 accountsd 飙到 180%,contactsd 和 itunescloudd 紧随其后。退出它没有用,因为你根本无法退出。重启能让情况好转,但只能撑一个小时。
这个问题从 3 月的 macOS Tahoe 26.4 就开始困扰 Mac 用户,到 26.5、26.6 依然存在,Apple 至今没有承认这个问题,而搜索结果里排名靠前的「重启 Mac / 重置 NVRAM」类文章里都找不到最可靠的修复方法——移除一个小组件。
本文将解释 peopled 到底是什么(我们扒开了它的内部),一个小组件为什么会让它陷入死循环,一个你可能根本不知道存在的文件夹上的隔离标记为何是另一个触发因素,以及应该按什么顺序去尝试这些修复方法。
核心要点
peopled是 Contacts 小组件背后的守护进程。 它的二进制文件中包含名为WidgetSuggester、WidgetConfigurationReader和CallHistoryFetcher的类,其沙盒配置文件又授予了它访问通话记录数据库的权限。这个组合正是死循环的根源。- 修复方法一:移除所有 Contacts 小组件——桌面、Notification Center 和 Control Center 都要清理干净——然后重启。这解决了 Apple 社区论坛上 54 份以上已确认报告中的大多数问题。
- 修复方法二:清除
~/Library/Application Support/CallHistoryDB上的隔离标记并终止peopled。当没有小组件可移除时就用这个方法;需要给 Terminal 授予 Full Disk Access。 - 修复方法三:关闭 iCloud Contacts,再重新开启。 对部分用户有效,并非人人适用,且关闭期间会失去同步。
- 配有 Exchange 或 Google 账户时
contactsd飙升是另一个更早的旧 bug,症状相同但修复方法不同——移除账户或改用第三方客户端。 - Apple 尚未在文档中给出修复方案。 26.4.1、26.5、26.6 及 26.6.x 的发布说明中均未提及此问题,26.5 及之后版本的相关报告仍在持续。
究竟是哪个进程
这些报告中出现了三个守护进程,它们并不能互相替代。在活动监视器里按 CPU 百分比排序,记下你遇到的是哪一个。
| 进程 | 所属模块 | 典型表现 | 最可能的原因 |
|---|---|---|---|
peopled | People framework——小组件建议、家人共享、Screen Time、状态 | 自 26.4 起持续保持在 70%–80% | Contacts 小组件 + 无法读取的 CallHistoryDB |
contactsd | Contacts framework——通讯录数据库与同步 | 每 60–90 秒飙升到 80%,或持续偏高 | iCloud/Exchange/Google 联系人同步死循环 |
accountsd | Accounts framework——每个已登录账户 | 与 contactsd、itunescloudd 一同飙到 180% | 账户身份验证死循环;注销修复往往无效 |
如果是 peopled,从小组件那一节开始看。如果只有 contactsd,直接跳到同步账户那一节。如果三个一起出现且 accountsd 占用最高,你遇到的是最不为人所知的变体,对应章节会坦诚地说明目前所知有多有限。
peopled 到底在做什么
名字听起来和联系人有关,仅有的几篇提到它的指南也把它描述成「管理联系人数据」。这个说法大体没错,但细节上是错的,而这个细节上的差异,正是为什么修复方法是移除小组件、而不是修复通讯录。
我们在一台运行 26.5.2 的 Mac 上查看了这个守护进程。它位于 /System/Library/PrivateFrameworks/People.framework/peopled,它的 launchd 任务(/System/Library/LaunchAgents/com.apple.peopled.plist)说明了是什么唤醒了它。它不会在登录时加载——RunAtLoad 为 false。它由以下事件启动:
missedCall、unreadMessage、readMessage、location、dndAvailability、screenTimeRequest、askToBuyRequest和childState这些 Biome 数据流- 两个系统通知:
__ABDataBaseChangedByOtherProcessNotification(通讯录发生变化)和_CalDatabaseChangedNotification(日历发生变化)
也就是说,每一通未接来电、每一条消息、每一次联系人编辑、每一次日历变更,都会唤醒 peopled。那么被唤醒之后它在做什么?它二进制文件里的字符串直接给出了答案。其中的 Swift 类名包括:
_TtC7peopled15WidgetSuggester
_TtC7peopled18CallHistoryFetcher
_TtC7peopled25WidgetConfigurationReader
而它的日志消息模板中包括:
Event triggered widget refresh: %{private}s, %s
Last widget suggestion date is older 24 hours, suggest widgets
Last widget suggestion date is within 24 hours, do not suggest widgets
error reading widgets configurations: %s
Failed to suggest widgets with error: %s
它链接了 Contacts framework、CallHistory framework 以及两个 Biome framework。就其自身代码所描述的而言,它的作用是以你最近的通话和消息为信号,决定在 Contacts 小组件和相关人物建议中该展示哪些人。
这也让这个故障模式说得通了:一个被每通电话和每条消息唤醒的守护进程,它的任务是刷新一个小组件,而要完成这个任务,它需要读取通话记录。

为什么会陷入死循环
把社区帖子里的线索和二进制文件所揭示的信息放在一起看。
peopled 运行在沙盒中。它的配置文件位于 /System/Library/Sandbox/Profiles/com.apple.peopled.sb,以 (deny default) 开头,然后逐一开放特定权限。其中两条是:
(home-subpath "/Library/CallHistoryDB/")
(home-subpath "/Library/Logs/CallHistory")
所以它被允许读取 ~/Library/Application Support/CallHistoryDB/,macOS 在这里保存通过 Continuity 从 iPhone 收发的通话记录数据库。这个文件夹同时也受 TCC 保护——在我们的 Mac 上,从 Terminal 对它执行 ls,在 Terminal 获得 Full Disk Access 之前会返回 Operation not permitted——这也是下面的修复方法都需要这项权限的原因。
现在来看具体的报告。4 月 21 日,Apple 社区帖子里有一位用户引用了他们在 peopled 空转时于 Console 中发现的内核消息:
Sandbox: peopled … deny(1) file-read-data ~/Library/Application Support/CallHistoryDB
5 月 20 日,另一位用户引用了:
failed to open /Users/[user]/Library/Application Support/CallHistoryDB: 1 (Operation not permitted)
综合这些信息,最合理的解读是:安装了一个 Contacts 小组件,于是 peopled 被要求刷新它;刷新意味着要抓取通话记录;这次抓取被拒绝——原因可能是这个文件夹被打上了 com.apple.quarantine 属性,也可能是报告没有查明的其他权限问题——刷新失败,紧接着下一个事件(或重试)又会再次触发它。一个本该在错过一通来电后运行几毫秒的守护进程,结果变成了持续运行。
我们想明确指出这里哪些是已确定的事实,哪些不是。类名、沙盒规则和日志消息都是我们直接读到的、可观察的内容。「小组件刷新、读取被拒、重试」这个死循环链条是一个推断,它符合我们看到的每一份报告,也符合两种确实有效的修复方法。Apple 尚未证实这个机制,而且可能还存在第二种触发方式——有一位用户报告称,死循环是在他重新整理 Control Center、且完全没有 Contacts 小组件的情况下开始的。
动手之前,先确认
花两分钟观察,能省下一小时瞎猜的功夫,而 CPU 占用的模式会告诉你该用哪个修复方法。
观察它的曲线形状。 在活动监视器中选中该进程,查看窗口底部的 CPU 历史记录,或者在 Terminal 中执行:
top -stats pid,command,cpu,time -o cpu -n 5
如果 peopled 稳定停在 70%–80%,那是小组件死循环。如果 contactsd 忽高忽低——飙升、归零、一分钟后再次飙升——那是同步死循环。三个守护进程同时持续占用 CPU,则是账户变体。
检查它已经运行了多久。 peopled 正常情况下只存活几秒钟。在我们(健康)的 Mac 上,它已经常驻了 41 天,CPU 占用为 0.0%——常驻但空闲是正常的。你要留意的是既常驻又忙碌的情况:
ps -axo pid,etime,pcpu,comm | grep -E "peopled|contactsd|accountsd"
寻找拒绝访问的记录。 这是决定性的测试。打开第二个 Terminal 窗口,在守护进程空转时实时查看它的日志:
log stream --predicate 'process == "peopled"' --info
然后在第一个窗口中,搜索最近几分钟内社区报告中引用的那条沙盒日志:
log show --last 10m --predicate 'eventMessage CONTAINS "Sandbox: peopled"'
如果你看到针对 CallHistoryDB 的 deny(1) file-read-data,说明你遇到的是 CallHistoryDB 变体,修复方法二会起作用。如果你看到 Event triggered widget refresh 反复出现却没有拒绝记录,先从修复方法一开始。如果日志很安静但 CPU 很高,说明死循环发生在默认级别不记录日志的代码里;这种情况下仍然按顺序依次尝试这几种修复方法。
如果想要百分之百确定,就监视文件系统。 fs_usage 会显示一个进程尝试的每一次文件操作,包括失败的那些:
sudo fs_usage -w -f filesys peopled
满屏都是对 CallHistoryDB 的操作尝试并返回错误,这就是死循环,实时可见。
修复方法一:移除 Contacts 小组件
这是得到最多确认的修复方法,也应该最先尝试,因为它是可逆的,而且不需要用到 Terminal。
需要注意的是,在 Tahoe 上小组件可能存在于三个位置,必须把这三处都清理干净。
桌面
按住 Control 点按桌面壁纸,选择编辑小组件。编辑状态下,桌面上任何 Contacts 小组件角落都会出现一个移除按钮(减号图标),点击它即可。也可以直接按住 Control 点按该小组件本身,选择移除小组件。最后点击完成。
Notification Center
点击菜单栏中的日期和时间以打开 Notification Center,滚动到底部,点击编辑小组件。用同样的方式移除其中的任何 Contacts 小组件——按住 Control 点按后选择移除小组件,或按住 Option 点击其移除按钮。
Control Center
这是最容易被忽略的一处,因为 Tahoe 把小组件也放进了 Control Center,而这项自定义设置并不在 System Settings 里。点击菜单栏中的 Control Center 图标,选择编辑控制项,把任何 Contacts 相关项目从 Control Center 中拖出来。点击完成。
然后重启——不是仅仅注销登录。帖子里有几份确认有效的修复都提到,CPU 只有在完整重启之后才会下降。
同一帖子里 7 月 31 日的报告还有一个额外提醒:对部分用户来说,哪怕没有重新添加 Contacts 小组件,只要再次打开小组件库,死循环就会卷土重来。如果你遇到过这个问题,在 Apple 修复这个守护进程之前,最好避免打开小组件编辑界面。
修复方法二:清除 CallHistoryDB 上的隔离标记
对于哪里都没有 Contacts 小组件、或者移除小组件也没用的 Mac,这是帖子里技术细节最详尽的一份报告在 5 月 20 日得出的修复方法,至少另外两位用户也确认了它的效果(一位用户在 6 月 26 日写道:「peopled process is now in 0% in CPU consumption」)。
第一步:给 Terminal 授予 Full Disk Access
系统设置 > 隐私与安全性 > 完全磁盘访问权限,添加 Terminal 并打开开关。不这样做的话,下面的每条命令都会报「Operation not permitted」——巧的是,这正是 peopled 遇到的同一个错误。授权后重启 Terminal。
第二步:查看这个文件夹
ls -lan@ "$HOME/Library/Application Support/CallHistoryDB"
@ 标志会显示扩展属性。你要找的是文件夹本身、或其内部 CallHistory.storedata 文件上的 com.apple.quarantine。隔离标记是 macOS 给下载文件打上的标记,它本不该出现在系统数据库上,至于它是怎么出现的,目前尚不清楚——从备份恢复、从另一台 Mac 迁移,是两条说得通的路径。
第三步:移除它
xattr -dr com.apple.quarantine "$HOME/Library/Application Support/CallHistoryDB"
-d 删除该属性,-r 递归处理整个文件夹。
第四步:重启守护进程
sudo killall -9 peopled CallHistorySyncHelper
两者都会按需重新启动。观察活动监视器几分钟。
如果标记又出现了
帖子里一位用户在 7 月 17 日报告说,这个修复方法起作用了,但隔离标记在一夜之间「reappeared」(又出现了)。如果你也遇到这种情况,说明有什么东西在重新给这个文件夹打上隔离标记,最可能的嫌疑对象是把它当成新数据处理的备份或同步工具。检查一下夜间都运行了什么。另外还有个更直接的做法,是另一位用户采用的:删除数据库,让 macOS 重新创建它:
rm -rf ~/Library/Application\ Support/CallHistoryDB
这样会丢失 Mac 本地保存的通话记录副本,之后会通过 Continuity 从 iPhone 重新同步回来。这比移除一个属性要激进得多,我们建议先尝试移除属性的方法。
修复方法三:切换 iCloud Contacts
System Settings > [你的名字] > iCloud > Saved to iCloud > Contacts,关闭它。等一分钟,观察 CPU。如果下降了,重新打开,看看它是否会保持在低位。
这对一部分用户有效,也是这类帖子多年以来的标准建议。它也有一种失败模式,一位用户在 5 月 11 日就遇到了:开关根本关不掉。如果遇到这种情况,就彻底退出 iCloud 登录(系统询问时选择保留一份数据副本),重启,再重新登录。需要说明的是,那位在 V2EX 上报告 accountsd 变体的用户正是这么试的,结果重新登录后 CPU 立刻又飙了回去。

如果是 contactsd,且你有 Exchange 或 Google 账户
这个问题在 Tahoe 之前就存在,机制也更加清晰。
contactsd 是 Contacts framework 的守护进程:它掌管通讯录数据库,并与每一个同步联系人的账户进行核对。它还会按计划做一些日常维护——它的 launchd 任务注册了一个每日的 validate-cache 任务,只在接外接电源、你不在使用电脑时运行,还有一个反复执行的 accounts.cleanup 活动。contactsd 偶尔出现短暂的 CPU 占用是正常现象。
不正常的是每隔一分钟左右就飙升一次。2025 年 12 月,一位开发者在 Apple Developer Forums 上记录了完全相同的情况:在一台运行 Tahoe 26.1 的 M1 Max 上,一个启用了 Contacts 的 Office 365 账户,让 AddressBookManager 飙到 81%、contactsd 飙到 22–59%,每 60–90 秒重复一次——即使把服务器上的 Exchange 联系人文件夹清空也是如此,而且在全新安装的系统上同样可以复现。同一个账户和数据放到 M4 Mac 或 iOS 上却不会出现这个问题。Apple 方面没有任何人回复。
他的变通方法确实有效:从 System Settings > Internet Accounts 中移除 Exchange 账户,如果还需要用它,改用不经过 Contacts framework 的 Outlook。2 月社区论坛上一份关于 2024 款 MacBook Pro、26.3 系统上 contactsd 的报告,得到的也是同样的建议——停止从 Exchange 和 Google 同步联系人并测试——如果你同时用 iCloud 和 Google 账户同步联系人,可以先尝试去掉 Google 那一个。
accountsd 变体
最严重的报告——一台运行 26.5.2 的 M5 MacBook Air 上,accountsd 飙到 180%,contactsd 和 itunescloudd 紧随其后,7 月在 V2EX 上有过描述——目前还没有确认有效的修复方法。报告者提到问题每天早上都在同一时间开始出现,这更像是指向了一个计划任务,而不是小组件事件。注销再重新登录也没有帮助。
我们能补充的是:accountsd 是 Accounts framework 的守护进程,只要有任何操作需要用到某个已登录账户的凭据,它就会被调用;itunescloudd 则是 iTunes Cloud(Apple Music / Store)资料库的守护进程。三者同时出现,意味着有什么东西在反复请求账户凭据却持续失败。如果你遇到的是这种变体,上面几种修复方法仍然值得按顺序尝试;如果都不管用,值得去 System Settings > Internet Accounts 里检查一下是不是某一个账户——一个很久没用的 Google 或 Exchange 登录、一个已过期的应用专用密码——正在验证失败。把任何显示警告标记的账户都移除掉。
为什么是 Tahoe,为什么是小组件
小组件在 Mac 上已经存在多年,所以有理由问一句:为什么这个问题从 26.4 才开始出现?有两件事同时发生了变化。
第一是小组件所在的位置。Tahoe 把小组件放进了 Control Center,与桌面和 Notification Center 并列,而 Control Center 里的 Contacts 小组件刷新节奏和放在桌面上的不一样——守护进程自己的日志模板就区分了每日的「建议小组件」流程(Last widget suggestion date is older 24 hours)和事件触发的刷新(Event triggered widget refresh)。承载的界面越多,刷新请求就越多,一次失败刷新被重试的机会也就越多。
第二是这个守护进程的错误处理逻辑似乎是「重试」而不是「退避」。这是我们从行为推断出的结论,并不是能直接从二进制文件里读出来的事实,但这正是真正的 bug 所在:一次被拒绝的读取本应只记录一次日志,然后放弃这次刷新,等待下一个真实事件到来。但实际情况是它会再次尝试,而触发它的事件又源源不断。
这两点都不是你能改变的。你能改变的是小组件是否存在、读取是否被拒绝,而这正是上面三种修复方法所做的事。
修复之后
有几件事能让修复效果保持下去。
如果你用了修复方法二,可以保留 Terminal 的 Full Disk Access,也可以特意收回——两种做法都可以,但要清楚自己做了哪一种,因为给 Terminal 授予 Full Disk Access 是一项范围很广的权限。
暂时避免打开小组件库。 帖子里 7 月 31 日的报告明确指出,仅仅是打开它——而不是添加任何东西——就会让死循环重新开始。如果你想添加其他小组件,做完之后记得检查一下活动监视器。
下一次 macOS 更新之后,再检查一遍。 小版本更新曾给部分用户重新添加过默认的 Control Center 项目,Contacts 小组件悄悄回归,是这个问题卷土重来最可能的原因。
提交反馈报告。 打开 Feedback Assistant,分类选 macOS,附上一份在 CPU 高企时采集的 sysdiagnose(在 Terminal 中执行 sudo sysdiagnose,或按 Shift-Control-Option-Command-句号),并粘贴那条沙盒拒绝日志。五个月的论坛帖子都没能推动这件事;几百份带着同一条日志的反馈报告或许可以。
修好了吗?
据目前所知,没有。我们查看了 Apple 的 Tahoe 更新说明:26.4.1「提供 bug 修复」,26.5「包含增强功能、bug 修复和安全更新」,26.6 优化了 Spotlight 索引,26.6.1 和 26.6.2 是安全更新版本。没有一条提到 Contacts、小组件或 CPU。在社区帖子里,26.5 上的报告仍在继续(5 月 15 日有用户写道:「The issue still exists in Tahoe 26.5. Apple needs to fix this asap.」),一直延续到 7 月。对于 8 月 17 日发布的 26.6.2,我们还没见到正反两方面的报告。
如果你在 macOS 27 beta 上遇到过或没遇到过这个问题,我们在beta 已知问题汇总里持续跟踪它。
不必浪费时间尝试的方法
重置 NVRAM 或 SMC。 两者都和用户空间守护进程的文件权限毫无关系。跳过。
tccutil reset All。 有用户试过,没有用,而且它会清空 Mac 上每个 App 的每一项隐私权限,之后你得花一下午重新逐个授权。没有理由认为出问题的是 TCC 这一层——日志里的拒绝记录来自沙盒,不是 TCC。
Safe Mode。 进入 Safe Mode 再退出会清除一些缓存,给部分用户带来过短暂缓解。这本质上是多几个步骤的重启,并没有解决根本原因。
用 launchctl 禁用 peopled。 你可以对这个代理执行 launchctl disable,它会因为停止运行而不再消耗 CPU。但这也会连带停掉 Contacts 小组件、人物建议、Screen Time 的「购买请求」等依赖它的功能,而且在启用了系统完整性保护的 Mac 上,这项改动可能撑不过下一次更新。除非是走投无路时用于诊断,否则不推荐这么做。
常见问题排查
活动监视器显示二十个 contactsd 副本
我们自己在写这篇文章时就遇到过:一瞬间冒出二十个 PID 连续的 contactsd 进程,都是 launchd 的子进程,CPU 占用都是 0%,一分钟内就消失了。这是 launchd 按需生成的逐客户端实例,不是那个 bug。真正的 bug 是某一个进程高 CPU 占用且一直不退。
Contacts 小组件已经移除,但 peopled 仍然占用 80%
检查全部三个位置——桌面、Notification Center、Control Center——然后再改用修复方法二。如果你从来没有添加过 Contacts 小组件,直接跳到修复方法二。
xattr 提示「No such xattr: com.apple.quarantine」
这个文件夹没有被隔离,所以这不是你的触发因素。尝试修复方法三,并检查一下是否有 Exchange 或 Google 账户在同步联系人。
对 CallHistoryDB 执行 ls,即使加了 sudo 仍提示「Operation not permitted」
sudo 不能绕过 TCC。需要给 Terminal 本身在 System Settings 中授予 Full Disk Access,然后重新启动它。
macOS 更新之后它又出现了
更新可能会把小组件重新加回 Control Center 的默认布局。再检查一遍那三个位置。
常见问题
peopled 是恶意软件吗?
不是。它是一个经过签名的 Apple 守护进程,位于受密封保护的系统卷上的 /System/Library/PrivateFrameworks/People.framework/peopled。如果一个同名进程从其他位置运行,那才值得调查;这一个是 Apple 自己的。
我可以直接杀掉它吗?
sudo killall peopled 能让它停下来,直到下一个事件把它唤醒——在繁忙的 Mac 上,这可能只要几秒钟。它可以用作诊断手段——如果杀掉之后 CPU 保持低位,说明触发因素已经消失——但不能算作修复。
移除小组件会丢失什么吗?
只会丢失这个小组件。Contacts、通话记录,以及 Spotlight 和 Messages 里的建议功能都照常工作;peopled 在需要时依然会运行。它只是不再被要求去刷新一个它根本刷新不了的东西。
为什么读取 CallHistoryDB 文件夹需要 Full Disk Access?
因为它包含你的通话记录,macOS 把这类数据视为敏感个人信息,像对待 Messages 和 Mail 一样用 TCC 加以保护。正是这层保护,让 Terminal 需要获得授权;也正是因为这层保护,一个意外出现的隔离标记才会造成这么大的破坏:这个守护进程只有一条狭窄的、经过沙盒限制的路径能访问这份数据,任何阻断这条路径的东西都会让它彻底失效。
macOS 27 会修复这个问题吗?
未知。Apple 尚未承认这个问题,beta 版发布说明里也完全没有提到它。如果证据所指向的机制是对的,那么修复起来其实很简单——失败一次就停止重试——而这样的修复完全可能悄无声息地出现在任何一个小版本更新里,不会被特意提及。
结语
一台什么都没做却在发烫的 Mac,几乎总是有某个进程陷入了死循环,而这个死循环的成因几乎总是很平淡无奇。这一次,是一个负责保持小组件更新的守护进程,它被每一通电话和每一条消息唤醒,却读不了它唯一需要的那个数据库。移除小组件,刷新请求就停了;修好文件夹的权限,读取就能成功。任何一种都能打破这个死循环。
如果你的活动监视器顶部是 peopled,按顺序依次尝试这三种修复方法,每种之间都重启一次。如果是配有 Exchange 或 Google 账户的 contactsd,移除那个账户。如果是三个守护进程一起出现、accountsd 排在最前面,把上面所有方法都试一遍,移除任何显示警告的账户,并且——因为 Apple 已经沉默了五个月——提交那份带着沙盒日志的 Feedback 报告,它或许终于能推动这个问题被修复。
延伸阅读:macOS 26.6 之后 Mac 发烫、耗电异常、Liquid Glass 与 26.5 上的 WindowServer CPU 占用、Tahoe 上 Contacts 应用无法正常工作、从零开始了解活动监视器,以及在 Tahoe 上自定义小组件。
