Mac 跑 Codex 跑到 100℃还有糊味:Node 140% 背后的原因和处理顺序

7次阅读
没有评论

今天在 Mac 上同时运行多个 Codex 任务时,机器温度升到了 100℃,活动监视器里一个 Node 进程长期占用约 140% CPU,内存一度接近 1.5 GiB。更让我紧张的是,机器附近还出现了一点焦糊味。

我第一反应是结束高占用进程,然后再追父进程、进程组和打开的文件。最后发现,问题并不是我正在开发的普通 Node 项目,也不是“Node 天生比 Java 更容易把电脑跑热”,而是某个超长 Codex 任务里的浏览器控制内核,在反复处理一份约 735 MiB 的会话日志。

这篇文章记录现场证据、正确的安全处置顺序,以及以后怎样避免同类任务再次把电脑拖到高温。

有焦糊味时,先别急着保留现场

CPU 温度短时间达到 100℃,不等于处理器已经烧坏。Mac 有温控、降频和保护机制,短时高温更常见的结果是性能下降、风扇高速运行或系统主动保护,而不是 CPU 立刻损坏。

但焦糊味不属于正常的软件现象。闻到焦味时,最优先的操作不是继续截图、跑测试或采样,而是:

  1. 完全关机,不是合盖休眠。
  2. 拔掉充电器和所有外设。
  3. 把电脑放到通风且不易燃的平面上,等它彻底冷却。
  4. 检查充电头、线缆、接口和机身是否有变色、变形、鼓起或持续发热,但不要自行拆机。
  5. 如果关机后仍有明显焦味、异常发热、鼓包、异响或烟雾,不要再次开机或充电,直接联系 Apple 或授权维修点。

软件现场可以重新复现,硬件和人身安全不能拿来换一份完整日志。

活动监视器里的 140% 到底是什么意思

macOS 的进程 CPU 百分比可以超过 100%。约 140% 通常表示这个进程消耗了大约 1.4 个逻辑核心,并不代表它占用了整台电脑 140% 的算力。

单看这个数字也不能判断是否异常。前端测试、视频编码、压缩和编译短时间达到 100% 以上很常见。真正需要警惕的是:

  • 占用持续数分钟不下降;
  • 进程处于运行态,不是在等待网络或磁盘;
  • 内存不断上涨并伴随频繁垃圾回收;
  • 杀掉子进程后,它马上被父进程重新拉起;
  • 温度、风扇和系统响应同时恶化。

这次现场中的 Node 同时符合这些特征。

这次不是普通 Node 服务,而是 Codex 浏览器内核

高占用进程的可执行文件位于 ChatGPT 应用内部,命令指向 cua_node/bin/node 和临时目录中的 kernel.js。它的父进程是 Codex sandbox,再往上是 node_repl 控制进程。

这解释了为什么只杀最下面的 Node 没用:控制进程仍然认为浏览器工具需要一个运行内核,于是很快又创建了新的 Node,PID 变了,但进程组没有变。

继续检查打开的文件时,lsof 显示这个内核正持有某个 Codex 会话的 JSONL 文件。文件大小为 770,845,459 字节,约 735 MiB。再用 macOS 自带的 sample 做 1 秒只读采样,调用栈里集中出现了:

  • 文件系统异步读取;
  • Buffer 和 TypedArray 复制;
  • UTF-8 字符串转换;
  • memmove 内存搬运;
  • V8 增量标记和垃圾回收。

这些证据组合起来,更像是浏览器工具在恢复上下文或处理工具结果时反复扫描大日志,而不是网页本身进行了正常计算。

为什么 Java 当时没事

语言不是决定温度的关键,实际工作负载才是。

当时同一台电脑上的 Spring Boot Java 服务只占用约 1% CPU,因为它主要在等待请求。高占用 Node 则在持续读文件、复制内存和做垃圾回收。如果让 Java 执行大型编译、测试、压缩或密集计算,它同样可以占满多个核心并把温度拉高。

此外,整机温度也不是一个 Node 独自造成的。现场同时存在 ChatGPT/Codex 主进程、渲染进程、Chrome Renderer、WindowServer 和短时运行的 Vitest。多个 30%~50% 的进程叠加,比单独盯着一个 node 名称更接近真实发热原因。

已经长到 735 MiB 的会话日志怎么处理

第一步不是直接删除 JSONL。Codex 仍在运行时手工删改会话文件,可能造成任务历史丢失、恢复失败或应用状态不一致。

更稳妥的处理顺序是:

  1. 在对应任务里停止浏览器验收,不再让它重连、截图或读取大 DOM。
  2. 把已经完成的结论、剩余事项和必要文件路径写成一份简短交接。
  3. 新建一个任务接着做后续工作,不让数百次工具调用继续堆在同一个会话里。
  4. 归档旧任务;需要保留证据时保留任务本身,不在运行期间直接改它的底层 JSONL。
  5. 完全退出 ChatGPT,再重新打开,让空闲的 node_repl 和已经失去父进程的内核统一退出。
  6. 如果同一会话再次稳定复现高占用,保留进程采样、日志大小和任务 ID,向 Codex 产品反馈性能问题。

换句话说,解决大日志的核心不是“把 735 MiB 压缩一下继续硬跑”,而是及时切断这个超长任务,让新任务从结构化交接和仓库文件接续。

以后怎样避免会话继续膨胀

长时间浏览器验收尤其容易制造大体积历史,因为 DOM 快照、截图、工具说明、控制台输出和失败重试都会进入任务记录。可以用下面几条规则降低风险:

  • 一个阶段完成后就开新任务,不用一句“继续”让同一任务无限增长。
  • 截图和报告保存到项目目录,任务里只记录路径与结论,不反复回显大块内容。
  • 浏览器固定少量页签,单页、单动作串行执行。
  • 避免同时读取两个大页面,也不要反复做整页截图和全量 DOM 扫描。
  • 插件连接连续超时后立即停止,不在同一任务里无限重连。
  • 每批浏览器验收结束就释放控制,不让 Node 内核长期常驻。
  • 活动监视器里出现持续高占用时,同时看命令、父进程、运行时长和内存,不要只按进程名称判断。

对复杂项目来说,长期状态应该落在代码、测试、报告和交接文档里,而不是只存在一个越来越大的聊天历史中。

冷却后怎样检查 Mac 有没有问题

电脑彻底冷却、焦味消失后,可以先做低负载检查,不要立刻跑压力测试:

  1. Apple 芯片 Mac 关机后长按电源键,看到“启动选项”后按 Command-D;Intel Mac 开机时按住 D,运行 Apple Diagnostics。
  2. 记录任何诊断参考代码。
  3. 查看“系统设置 → 电池 → 电池健康”,确认是否出现建议维修。
  4. 开机空闲 10~15 分钟,观察 CPU、温度和风扇是否恢复正常。
  5. 即使诊断通过,只要焦味再次出现,也应停止使用并送检。软件诊断无法排除所有间歇性的电池、供电、接口或散热问题。

Apple 官方说明可参考:使用 Apple Diagnostics 测试 Mac

这次离线检测得到 ADP000,能说明什么

这次 Apple Diagnostics 没有连上在线支持服务,只完成了离线检测,但最终仍明确显示 No issues found,参考代码为 ADP000。这说明诊断程序在本轮硬件自检中没有发现可识别的问题,是一个积极信号;离线模式主要影响在线说明和后续支持入口,不等于本轮基础硬件检测没有运行。

不过,ADP000 不是“所有硬件绝对正常”的终身证明。间歇性的电池、供电、接口接触、风扇或散热问题,可能在冷却后的单次检测里不出现。因此更稳妥的结论是:当前没有检测到明确硬件故障,可以低负载观察;如果焦味、局部异常发热、鼓包、意外关机或充电异常再次出现,仍应立即停机并送检,而不是用 ADP000 继续冒险。

最后的判断

这次最关键的发现不是“Node 很危险”,而是一个具体的异常组合:超长 Codex 浏览器任务、735 MiB 会话日志、反复重连和截图、子进程自动重建,再叠加多个活跃应用,最终把 Mac 推到了持续高温。

高温时先停任务、杀掉异常负载是对的;出现焦糊味后,关机、断电和硬件检查应立即排到软件排查之前。等设备确认安全,再用进程树、lsof 和短时 sample 定位根因,比在活动监视器里随机结束一批名字相似的 Node 更可靠。

后续怎样限制浏览器重试、控制页签数量、设置会话日志提醒线,以及避免误伤正常 Node 构建,我另写了一篇:Codex 控制浏览器时怎样避免 Node 再次吃满 Mac CPU

本文记录的是一次本机排查经历,不替代 Apple 的硬件诊断或维修意见。

正文完
 0
bdspAdmin
版权声明:本站原创文章,由 bdspAdmin 于2026-07-20发表,共计3148字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)