记录时间:2026-06-08
实测环境:macOS 26.5(Build 25F71,Apple Silicon)
涉及应用:IntelliJ IDEA、Codex、CC Switch
本次实测 IDEA 版本:IntelliJ IDEA 2026.1.2
本次实测 JetBrains Runtime:JBR 25.0.2
本次实测 Codex 版本:26.602.40724
一、问题现象
某些 macOS 桌面应用原本可以正常运行,卡死后被强制退出,随后出现以下现象:
- 再次点击 Dock、Launchpad 或“应用程序”中的图标,没有任何可见反应。
- 执行
open -a "应用名称",命令很快返回,但应用窗口没有出现。 - 杀掉应用相关进程后仍无法启动。
- 重新安装应用通常不是必需的。
- 重启 Mac 后应用又可以正常启动。
- 问题不是固定发生在一个应用上,IntelliJ IDEA、Codex、CC Switch 都曾出现过。
这类现象很容易被误判为:
- App 文件损坏;
- 应用缓存损坏;
- 应用锁文件没有删除;
- Java 进程没有杀干净;
- Dock 或 LaunchServices 缓存异常。
本次现场排查表明,实际问题至少分成两层:
- 应用为什么会先卡死;
- 强制退出后,为什么新进程无法完成启动。
这两层问题必须分开分析。
二、结论摘要
2.1 IDEA 最初卡死的直接原因
IDEA 的多份 freeze thread dump 显示:
- UI 主线程
AWT-EventQueue-0一直等待Java2D Disposer; Java2D Disposer又在等待 macOS Metal 渲染队列;- 关键调用包括:
sun.java2d.metal.MTLRenderQueue.flushAndInvokeNow sun.java2d.Disposer FontStrikeDisposer StrikeCache.disposeStrike这说明 IDEA 最初的卡死发生在JetBrains Runtime 的 Java2D Metal 渲染路径。
本次对 IDEA 增加了下面的用户级 JVM 参数:
-Dsun.java2d.metal=false该参数关闭 Java2D 的 Metal 渲染后端,改用其他渲染路径,用来规避这类 Metal 渲染线程卡死。
2.2 强制退出后无法再次启动的直接原因
IDEA 被强制退出后,新启动出来的 IDEA 进程并不是一个正常 JVM,而只是一个很小的启动器空壳。
对启动器采样后发现,线程卡在:
JNI_CreateJavaVM LoadJavaVM dlopen dyld4::Loader::mapSegments fcntl也就是说:
新 IDEA 还没有创建 JVM,也没有读取 IDEA 的锁文件、缓存或项目配置,就已经卡在 macOS 动态库装载和系统策略校验阶段。
与此同时,macOS 的syspolicyd日志持续出现:
UNIX error exception: 24 Failed to generate SecStaticCode ... error: 100024 failed to call driver: 0x3其中 Unixerrno 24的含义是:
EMFILE: Too many open files进一步检查syspolicyd的文件描述符时发现:
- 该进程打开了约 2575 个文件句柄;
- 其中约 2536 个句柄都重复指向:
/Applications/Codex.app/Contents/MacOS/Codex因此,本次“强退后再次点击没有反应”的直接原因是:
macOS 的系统策略服务
syspolicyd出现了文件描述符泄漏或异常积压,无法继续完成新可执行文件和动态库的代码签名、来源及安全策略检查。新应用虽然被 LaunchServices 创建了进程,但进程卡在非常早期的加载阶段。
2.3 为什么重启 Mac 一定有效
重启会同时完成下面几件事:
- 结束异常的
syspolicyd; - 清空它泄漏或积压的文件描述符;
- 清理 LaunchServices、RunningBoard 中记录的半启动应用状态;
- 清除应用启动器空壳;
- 重新初始化动态链接和代码校验相关系统服务。
所以重启能恢复,但这并不代表 App 文件已经被重装修复。
三、IDEA、Codex、CC Switch 三个问题是否有关
3.1 有关联,但不是“IDEA 导致其他两个应用坏了”
更准确的关系是:
IDEA、Codex、CC Switch │ ├── 各自可能有不同的初始卡死原因 │ └── 强制退出后重新启动时,都要经过相同的 macOS 启动基础设施 │ ├── LaunchServices ├── RunningBoard ├── dyld ├── amfid └── syspolicyd因此:
- IDEA 的 Metal 渲染卡死,只解释 IDEA 为什么先失去响应;
- 它不能解释 Codex 和 CC Switch 以前为什么也出现过相同症状;
- 三个应用共同出现“强退后无法再次启动、重启后恢复”,说明它们很可能共享了同一类系统启动层故障;
- 本次现场已经实证
syspolicyd发生文件描述符耗尽; - 以前 Codex、CC Switch 出现问题时没有保留当时日志,因此只能判断为高度可能属于同一故障类型,不能百分之百断言当时也是同一个 PID、同一个泄漏目标。
3.2 Codex 在本次故障中的角色
本次重启syspolicyd后,新的syspolicyd很快又出现大量重复打开 Codex 主程序的文件句柄。
这说明当前环境中:
Codex 相关的可执行文件校验或其子进程来源校验,是触发、放大或暴露
syspolicyd文件描述符泄漏的重要条件。
但是,不能仅凭这个现象就断言“Codex 应用逻辑主动泄漏了文件”。
原因是这些句柄属于 root 用户运行的syspolicyd,不是 Codex 自己的句柄。更可能的情况是:
- Codex 或 Codex 启动的子进程频繁触发 macOS provenance/code-signing 检查;
- macOS 26.5 的
syspolicyd在处理这些请求时没有正确关闭 Codex 主程序句柄; - 请求积累后,
syspolicyd达到自己的文件描述符上限; - 后续任何应用的代码校验或动态库装载都可能被拖死。
3.3 Codex 是否被本地命令改坏
本次从 OpenAI 官方地址重新下载了 Codex DMG,并做了只读对照:
- 官方 DMG 校验通过;
- 官方 DMG 内的 Codex 版本也是
26.602.40724; - 官方包中的 Codex 主程序与
/Applications/Codex.app主程序 SHA-256 完全一致; - 官方包和已安装副本在当前 macOS 上执行严格
codesign --verify时表现一致。
所以:
当前
/Applications/Codex.app不是被用户历史命令单独改坏的副本。重新安装完全相同的官方版本,未必能解决当前syspolicyd问题。
更值得关注的是:
- macOS 26.5;
- Codex 26.602.40724;
- 系统策略服务
syspolicyd; - Codex 及其子进程触发的 provenance/code-signing 校验;
- 这几者之间的组合行为。
3.4 CC Switch 的情况
历史中执行过:
codesign--force--deep--sign- /Applications/CC\Switch.app xattr-cr/Applications/CC\Switch.app它们的影响是:
codesign --sign -会把 CC Switch 改成 ad-hoc 签名;--deep会递归处理应用包中的嵌套组件;xattr -cr会递归移除隔离、来源和其他扩展属性;- 这些修改只直接作用于 CC Switch,不会直接修改 IDEA 或 Codex。
因此:
- 它们不能解释 IDEA 和 Codex 也出现同类问题;
- 它们可能让 CC Switch 自己的签名、更新和系统来源校验变得更复杂;
- 后续不建议把“重新签名整个 App”作为常规修复手段。
四、历史命令与本次故障的关系
| 历史操作 | 是否是本次根因 | 说明 |
|---|---|---|
git commit、git remote、git push | 否 | 与 macOS 应用启动链路无关 |
设置或取消HTTP_PROXY、HTTPS_PROXY | 基本无关 | 只影响网络请求和 Homebrew 下载,不会造成本地 JVM 卡在dlopen/fcntl |
| Homebrew 下载 CC Switch 失败 | 否 | 只是代理端口配置错误 |
npm run dev | 否 | 与 IDEA 主程序装载无直接关系 |
pkill -f "IntelliJ IDEA" | 是触发动作,不是根因 | 强制终止了应用,但没有修复已经异常的系统策略服务 |
pkill -f "fsnotifier" | 不是根因 | 只影响 JetBrains 文件监控子进程 |
open -a "IntelliJ IDEA" | 不是根因 | 只是提交启动请求;系统服务异常时它可能无错误返回 |
对 CC Switch 执行codesign --force --deep --sign - | 只影响 CC Switch | 可能带来 CC Switch 自身签名和更新风险,但不会直接改坏 IDEA 或 Codex |
对 CC Switch 执行xattr -cr | 只影响 CC Switch | 移除该 App 的扩展属性,不是全局修复 |
五、为什么open -a没报错,但应用就是不出来
open -a的主要职责是把启动请求交给 LaunchServices。
它不是在当前终端中同步等待应用完成所有初始化。
本次系统日志显示:
- RunningBoard 接受了 IDEA 启动请求;
- 系统成功创建了 IDEA PID;
- RunningBoard 把它标记为
running-active; - 但 IDEA 启动器在创建 JVM 时卡住;
- 因为系统已经认为 Bundle ID 对应的应用正在运行,后续点击图标可能只会尝试激活这个半启动进程;
- 所以用户看到的效果就是“点击完全没反应”。
这类进程通常具有以下特点:
- PID 存在;
- CPU 很低;
- RSS 内存只有几 MB;
- 没有完整 JVM 线程;
- 没有打开 IDEA 的配置、缓存、项目文件和本地端口;
sample显示卡在dlopen、dyld、fcntl、codesign或安全策略相关调用。
六、下次遇到问题时的 5 分钟无重启恢复流程
以下流程优先恢复系统,不删除应用数据,也不重装应用。
第 0 步:保存其他应用中的工作
重启syspolicyd通常不会关闭普通应用,但执行任何系统级恢复前,都建议先保存正在编辑的文件。
如果 Codex 正在运行,并且不是用 Codex 自己排查问题,建议先正常退出 Codex,避免它继续创建子进程并触发新的校验请求。
第 1 步:确认目标应用有没有留下空壳进程
IDEA:
ps-axopid,ppid,%cpu,%mem,rss,state,lstart,command\|grep-E'/Applications/IntelliJ IDEA.app/Contents/MacOS/idea|fsnotifier'\|grep-vgrepCodex:
ps-axopid,ppid,%cpu,%mem,rss,state,lstart,command\|grep-E'/Applications/Codex.app/Contents/MacOS/Codex'\|grep-vgrepCC Switch:
ps-axopid,ppid,%cpu,%mem,rss,state,lstart,command\|grep-Ei'CC Switch|cc-switch|ccswitch'\|grep-vgrep如果目标应用的主进程存在,但内存很小、长时间没有窗口,可以先记录 PID。
第 2 步:确认syspolicyd是否异常
查看 CPU:
ps-axopid,ppid,user,%cpu,%mem,state,lstart,command\|grep'[s]yspolicyd'正常情况下,syspolicyd不应该长时间占用很高 CPU。
检查最近错误:
log show--last10m--stylecompact\--predicate'process == "syspolicyd"'\|grep-E'UNIX error exception: 24|Failed to generate SecStaticCode|failed to call driver'如果反复看到:
UNIX error exception: 24基本可以确认syspolicyd已达到文件描述符上限。
检查打开文件总数:
sudolsof-nP-p"$(pgrep-xsyspolicyd)"|wc-l检查是否大量重复打开某个 App:
sudolsof-nP-p"$(pgrep-xsyspolicyd)"\|awk'NR > 1 { name = $9 for (i = 10; i <= NF; i++) name = name " " $i count[name]++ } END { for (name in count) print count[name], name }'\|sort-nr\|head-n20如果前几名出现数百或数千次相同的 App 主程序,说明已经抓到非常强的文件描述符泄漏证据。
第 3 步:结束目标应用的半启动空壳
先使用普通TERM:
kill<目标应用PID>等待两秒后确认:
ps-p<目标应用PID>只有进程仍然存在时,才使用:
kill-9<目标应用PID>注意:
- 不要对不确定的 PID 直接执行
kill -9; - 如果应用已经完整启动并可能有未保存数据,应先正常退出;
- 本次 IDEA PID
21412已确认没有创建 JVM,因此结束它不会丢失项目编辑状态。
第 4 步:只重启syspolicyd
在终端执行:
sudokillallsyspolicyd输入 Mac 管理员密码。
syspolicyd是 launchd 管理的系统服务。终止旧进程后,macOS 会自动启动一个新的实例。
检查 PID 是否变化:
pgrep-lfsyspolicyd本次实测中:
- 旧 PID 为
495; - 重启后变成
91960; - 再次重启后又变成
87102。
PID 变化说明系统服务已经被重新拉起。
不要使用下面这条命令作为首选:
sudolaunchctl kickstart-ksystem/com.apple.security.syspolicy本次在开启 SIP 的正常系统中,该命令返回:
Operation not permitted while System Integrity Protection is engaged没有必要为了这件事关闭 SIP。
第 5 步:重新启动应用
IDEA:
open-na"IntelliJ IDEA"Codex:
open-na"Codex"CC Switch:
open-na"CC Switch"如果应用本来就支持单实例,也可以使用:
open-a"应用名称"在已经清理空壳进程的前提下,-n可以明确要求 LaunchServices 创建新实例。
第 6 步:验证不是“又启动了一个空壳”
以 IDEA 为例:
ps-axopid,ppid,%cpu,%mem,rss,state,lstart,command\|grep'/Applications/IntelliJ IDEA.app/Contents/MacOS/idea'\|grep-vgrep完整 IDEA JVM 通常会占用数百 MB 到数 GB 内存,而不是几 MB。
继续确认:
ps-axopid,ppid,command\|grep-E'fsnotifier|jetbrainsd'\|grep-vgrep查看最新 IDEA 日志:
tail-n100"$HOME/Library/Logs/JetBrains/IntelliJIdea2026.1/idea.log"看到插件加载、项目加载、索引等日志,说明 IDEA 已经越过启动器和 JVM 创建阶段。
七、IDEA 专项修复:关闭 Java2D Metal
7.1 推荐方法
IDEA 能启动时,在菜单中打开:
Help -> Edit Custom VM Options加入:
-Dsun.java2d.metal=false然后完全退出并重新启动 IDEA。
7.2 IDEA 无法启动时手动修改
本次 IDEA 2026.1 的用户级 VM 参数文件是:
~/Library/Application Support/JetBrains/IntelliJIdea2026.1/idea.vmoptions查看文件:
cat"$HOME/Library/Application Support/JetBrains/IntelliJIdea2026.1/idea.vmoptions"避免重复添加:
VM_OPTIONS="$HOME/Library/Application Support/JetBrains/IntelliJIdea2026.1/idea.vmoptions"grep-qxF--'-Dsun.java2d.metal=false'"$VM_OPTIONS"\||printf'%s\n''-Dsun.java2d.metal=false'>>"$VM_OPTIONS"本次最终文件内容为:
# custom IntelliJ IDEA VM options (expand/override 'bin/idea.vmoptions') -Dsun.java2d.metal=false7.3 如何确认参数已经生效
执行:
grep-F--'-Dsun.java2d.metal=false'\"$HOME/Library/Logs/JetBrains/IntelliJIdea2026.1/idea.log"\|tail本次新启动日志的JVM options同时出现:
-Dsun.java2d.metal=true -Dsun.java2d.metal=false后出现的用户自定义参数会覆盖前面的默认值,因此最终使用false。
7.4 不要修改 App 包里的默认 VM 参数
不要直接编辑:
/Applications/IntelliJ IDEA.app/Contents/bin/idea.vmoptions原因:
- 更新 IDEA 时可能被覆盖;
- 修改 App Bundle 内容可能破坏代码签名;
- JetBrains 提供了用户级 Custom VM Options 机制,应该优先使用它。
JetBrains 官方说明:
- Tuning the IDE
八、完整深度排查流程
当快速恢复流程无效时,按以下顺序定位。
8.1 先判断应用处在哪个启动阶段
情况 A:完全没有 PID
可能原因:
- LaunchServices 没有真正创建进程;
- App Bundle 注册异常;
- 路径或 Bundle ID 不正确;
- 系统安全策略直接拒绝启动。
检查:
open-a"应用名称"echo$?然后查看:
log show--last5m--stylecompact\--predicate'process == "launchservicesd" OR process == "runningboardd" OR process == "amfid"'情况 B:PID 存在,但内存只有几 MB
这通常是启动器空壳。
执行采样:
sample<PID>51-file"$HOME/Desktop/app-launch.sample.txt"重点搜索:
grep-E'JNI_CreateJavaVM|dlopen|dyld|fcntl|codesign|syspolicy'\"$HOME/Desktop/app-launch.sample.txt"如果卡在dlopen/dyld/fcntl,优先排查syspolicyd,不要先删除应用缓存。
情况 C:完整 JVM 已经启动,但没有窗口
可能原因:
- 窗口状态恢复异常;
- 插件卡死;
- 项目加载卡死;
- 单实例锁或本地端口异常;
- UI 线程死锁;
- 图形渲染问题。
此时再检查:
jcmd<IDEA_PID>Thread.print-l如果jcmd自己也长时间卡住,要重新考虑底层系统服务是否异常。
情况 D:完整 JVM 已启动,而且 CPU 或内存异常
重点分析:
- IDEA freeze thread dump;
- GC;
- 插件;
- 索引;
- 文件系统监听;
- Java2D、Metal 或 Skia 渲染;
- 外部构建进程。
8.2 检查 IDEA freeze dump
目录:
~/Library/Logs/JetBrains/IntelliJIdea2026.1/threadDumps-freeze-*查找 Metal 渲染调用:
grep-R-n-E'MTLRenderQueue|Java2D Disposer|StrikeCache|FontStrikeDisposer'\"$HOME/Library/Logs/JetBrains/IntelliJIdea2026.1"/threadDumps-freeze-*\|head-n100本次的关键关系是:
AWT-EventQueue-0 waits for Java2D Disposer Java2D Disposer waits for MTLRenderQueue这不是普通的项目索引慢,而是 UI 渲染链路阻塞。
8.3 检查 IDEA 自带 JBR 是否能独立启动
"/Applications/IntelliJ IDEA.app/Contents/jbr/Contents/Home/bin/java"-version正常时应该很快输出版本。
本次在syspolicyd异常时,该命令超过 12 秒仍无输出;重启syspolicyd后立刻输出:
openjdk version "25.0.2" OpenJDK Runtime Environment JBR-25.0.2 OpenJDK 64-Bit Server VM JBR-25.0.2这个对照可以证明:
- JBR 文件本身并未损坏;
- 卡住的是系统装载和校验链路;
- 重装 IDEA 不是当时最有效的动作。
8.4 检查锁文件,但不要把锁文件当成默认根因
IDEA 常见文件:
~/Library/Application Support/JetBrains/IntelliJIdea2026.1/.lock ~/Library/Caches/JetBrains/IntelliJIdea2026.1/.port只有满足下面条件时,才考虑删除:
- 已确认没有任何 IDEA 主进程;
- 已确认没有 JetBrains 后台组件仍在使用;
- 日志明确指向单实例锁或端口;
- 备份或记录了原文件。
本次 IDEA 启动器在打开这些文件之前就已经卡住,因此删除.lock或.port不能解决本次根因。
8.5 检查系统内存压力
memory_pressure vm_stat本次 Mac 有 64GB 内存,空闲充足,没有 swap、压缩和 pageout 压力,因此不是内存不足。
8.6 检查 App 签名时要谨慎解释结果
查看签名:
codesign-d--verbose=4"/Applications/应用名称.app"验证:
codesign--verify--deep--strict--verbose=4"/Applications/应用名称.app"查看 Gatekeeper:
spctl--statusspctl--assess--typeexecute--verbose=4"/Applications/应用名称.app"注意:
codesign --verify失败不一定能单独证明本地文件被篡改;- 应与官方包做哈希和签名对照;
- 本次官方 Codex DMG 与已安装 Codex 的主程序哈希相同;
- 当前系统中
spctl --status显示 assessments disabled,这不是本次文件描述符泄漏的直接原因,但会让签名问题更难判断; - 不要为了绕过提示长期关闭 Gatekeeper,更不要为了本问题关闭 SIP。
九、Codex 的长期处理建议
9.1 当前版本不建议单纯重复安装
本次官方 DMG 与已安装副本版本和主程序哈希一致。
因此,在仍然是26.602.40724的情况下,简单地“删除后重新安装同一个包”未必能改变syspolicyd的表现。
9.2 优先升级到后续 Codex 版本
当 OpenAI 发布新版本后:
- 正常退出 Codex;
- 安装新的官方版本;
- 不要自行对 Codex 执行
codesign --force --deep --sign -; - 不要对 Codex 执行递归
xattr -cr作为常规操作; - 升级后观察
syspolicyd是否还会大量重复打开 Codex 主程序。
查看当前版本:
/usr/libexec/PlistBuddy\-c'Print :CFBundleShortVersionString'\"/Applications/Codex.app/Contents/Info.plist"OpenAI 官方 Codex App 文档:
- Codex App
Apple Silicon 官方安装包:
- Codex.dmg
9.3 如果问题复现,先退出 Codex 再重启syspolicyd
如果不是在 Codex 中排查,可先正常退出 Codex,然后执行:
sudokillallsyspolicyd再启动目标应用。
这样可以避免重启后的syspolicyd立即继续接收大量来自 Codex 子进程的校验请求。
9.4 保存可提交给 OpenAI 或 Apple 的证据
复现后立即执行:
mkdir-p"$HOME/Desktop/app-launch-diagnosis"ps-axopid,ppid,user,%cpu,%mem,rss,state,lstart,command\>"$HOME/Desktop/app-launch-diagnosis/processes.txt"log show--last15m--stylecompact\--predicate'process == "syspolicyd" OR process == "amfid" OR process == "launchservicesd" OR process == "runningboardd"'\>"$HOME/Desktop/app-launch-diagnosis/system-launch.log"sudolsof-nP-p"$(pgrep-xsyspolicyd)"\>"$HOME/Desktop/app-launch-diagnosis/syspolicyd-lsof.txt"如果目标应用留下空壳:
sample<目标应用PID>101\-file"$HOME/Desktop/app-launch-diagnosis/app-launch.sample.txt"提交日志前应先检查其中是否包含:
- 用户名;
- 项目路径;
- 本地文件名;
- 网络地址;
- Token;
- 其他隐私信息。
十、CC Switch 的长期处理建议
10.1 不再把 ad-hoc 重签作为常规方案
下面这类命令只适合明确知道签名后果时使用:
codesign--force--deep--sign-"/Applications/CC Switch.app"风险包括:
- 改变原开发者签名;
- 破坏自动更新校验;
- 嵌套组件签名状态变化;
- 与系统 provenance、Gatekeeper 记录不一致;
- 后续难以判断到底是官方包问题还是本地修改问题。
10.2 出现同类现象时先检查系统层
如果 CC Switch 再次出现:
- 点击无反应;
open -a "CC Switch"无明显报错;- 重启 Mac 后恢复;
应先检查:
log show--last10m--stylecompact\--predicate'process == "syspolicyd"'\|grep-E'UNIX error exception: 24|Failed to generate SecStaticCode'不要立刻再次重签整个 App。
十一、不要优先做的操作
11.1 不要反复点击图标或循环执行open -a
它不会修复系统策略服务,还可能产生更多半启动请求和日志噪声。
11.2 不要一上来就删除整个应用配置目录
例如不要直接删除:
~/Library/Application Support/JetBrains ~/Library/Caches/JetBrains ~/Library/Application Support/Codex本次根因发生在应用读取这些目录之前,删除配置只会丢失设置,不能修复syspolicyd。
11.3 不要默认删除.lock和.port
只有日志和进程状态证明是单实例锁问题时才处理。
11.4 不要随意重建 LaunchServices 数据库
LaunchServices 只是把进程创建出来。本次真正阻塞发生在进程创建后的 JVM/动态库装载阶段。
11.5 不要关闭 SIP
本问题不需要关闭 SIP。
11.6 不要长期关闭 Gatekeeper
本次系统显示 Gatekeeper assessments disabled。虽然这不是syspolicyd泄漏的直接原因,但长期关闭会降低下载应用的安全校验能力,也会使签名排查失去重要参照。
11.7 不要把kill -9当作第一选择
先尝试正常退出或kill。只有进程不响应并且已确认无未保存状态时才使用kill -9。
十二、本次实际执行的恢复步骤
本次没有重启 Mac,实际完成了以下操作:
- 确认 macOS 版本为 26.5,系统内存充足;
- 找到 IDEA 空壳进程 PID
21412; - 使用
lsof证明该进程没有打开 IDEA 配置、缓存和锁文件; - 使用
sample证明它卡在JNI_CreateJavaVM -> dlopen -> dyld -> fcntl; - 使用 IDEA freeze dump 证明原始 UI 卡死发生在 Java2D Metal 渲染链路;
- 从
syspolicyd日志中确认errno 24; - 发现
syspolicyd大量重复打开 Codex 主程序; - 使用管理员权限终止旧
syspolicyd,由 launchd 自动拉起新实例; - 验证 IDEA 自带 JBR 的
java -version恢复正常; - 在用户级
idea.vmoptions中加入:
-Dsun.java2d.metal=false- 结束 IDEA 空壳进程;
- 再次重启
syspolicyd; - 执行:
open-na"IntelliJ IDEA"- IDEA 成功启动为完整 JVM;
- 新 IDEA PID 为
18337,RSS 约 1.7GB; fsnotifier和jetbrainsd均正常启动;- IDEA 日志进入项目加载和索引阶段;
- IDEA 日志确认
-Dsun.java2d.metal=false已生效。
十三、下次处理时的最短命令清单
确认目标应用和系统服务:
ps-axopid,ppid,user,%cpu,%mem,rss,state,lstart,command\|grep-E'[s]yspolicyd|IntelliJ IDEA|Codex|CC Switch'确认syspolicyd是否报文件句柄耗尽:
log show--last10m--stylecompact\--predicate'process == "syspolicyd"'\|grep-E'UNIX error exception: 24|Failed to generate SecStaticCode'检查句柄总数和重复目标:
sudolsof-nP-p"$(pgrep-xsyspolicyd)"|wc-lsudolsof-nP-p"$(pgrep-xsyspolicyd)"\|grep'/Applications/'\|awk'{print $9}'\|sort\|uniq-c\|sort-nr\|head结束已经确认的应用空壳:
kill<空壳PID>重启系统策略服务:
sudokillallsyspolicyd重新启动 IDEA:
open-na"IntelliJ IDEA"确认 IDEA 完整启动:
ps-axopid,ppid,%cpu,%mem,rss,state,lstart,command\|grep'/Applications/IntelliJ IDEA.app/Contents/MacOS/idea'\|grep-vgreptail-n100"$HOME/Library/Logs/JetBrains/IntelliJIdea2026.1/idea.log"十四、最终判断
本次问题不是一个单点故障,而是两层问题叠加:
第一层: IDEA 的 Java2D Metal 渲染线程卡死 ↓ 用户强制退出 IDEA 第二层: macOS syspolicyd 已发生文件描述符泄漏/耗尽 ↓ 新 IDEA 在 JVM 和动态库装载阶段卡住 ↓ LaunchServices 认为应用已经启动 ↓ 再次点击图标或 open -a 看起来完全没反应因此,最终解决方案也分为两部分:
- 恢复启动能力:结束应用空壳,并重启
syspolicyd; - 降低 IDEA 再次卡死概率:加入
-Dsun.java2d.metal=false。
对于 Codex 和 CC Switch:
- 它们与 IDEA 不是同一个应用级故障;
- 但很可能共享同一个 macOS 系统启动层故障;
- 本次 Codex 明确与
syspolicyd的重复文件句柄现象相关; - 以前两次由于没有保存现场日志,只能归类为高度相似,不能做百分之百的历史追溯。
如果以后再次发生,优先执行本文的“5 分钟无重启恢复流程”,不需要一开始就重启整台 Mac、重装应用、删除配置或重新签名 App。