GHCi 在 VSCode 中卡住或崩溃是因堆内存超默认1.4GB上限,需通过 stack.yaml(ghc-options)或 settings.json(serverExecutableArguments)传 -with-rtsopts=-M2g;同时配置 files.watcherExclude 排除 node_modules 等目录,并彻底重启 VSCode 使参数生效。

为什么 GHCi 在 VSCode 里卡住或崩溃?
不是代码写错了,而是 ghci 进程自己堆内存爆了。VSCode 的 Haskell 扩展(如官方 Haskell 插件)默认调用系统 ghci,但不传任何 Node.js 或 GHC 运行时内存参数——而 GHCi 在加载大型模块、启用 -XTemplateHaskell、或反复重载含大量依赖的文件时,很容易突破默认的 1.4GB 堆上限,直接触发 Fatal error: out of memory 或静默退出。
怎么给 ghci 单独设内存上限?
VSCode 不控制 ghci 的启动参数,得靠你手动干预它的调用方式。关键路径有两条:
- 如果你用的是
stack ghci(推荐):在项目根目录的stack.yaml里加ghc-options: { "$locals": "-with-rtsopts=-M2g" }—— 注意单位是2g(2GB),不是 MB;-M是 GHC RTS 的堆上限开关,必须小写 - 如果你直连系统
ghci(比如没配 stack):在 VSCode 的settings.json中配置haskell.serverExecutableArguments,例如:"haskell.serverExecutableArguments": ["--ghci-options=-with-rtsopts=-M2g"]
——这个只影响 HLS 启动的 ghci 子进程,对终端里手动敲的ghci无效 - 别碰
NODE_OPTIONS=--max-old-space-size:那是给 Node.js 进程用的,ghci是纯 Haskell 进程,完全不认这个
files.watcherExclude 对 ghci 内存没用,但会间接救它
files.watcherExclude 本身不约束 ghci,但它能大幅减少 HLS 需要扫描和缓存的文件数。如果 **/node_modules/** 漏配,HLS 可能把整个 node_modules 下的 .hs 文件都扔进类型检查队列,再喂给 ghci 加载——结果就是 ghci 尝试解析上千个无关模块,堆瞬间拉满。
必须确保该配置写在项目根目录的 .vscode/settings.json 中,且格式严格:
-
"**/node_modules/**": true✅(双星号 + 尾部斜杠) -
"**/node_modules": true❌(VSCode 忽略) - 顺手加上
"**/.stack-work/**": true和"**/dist-newstyle/**": true,这些目录里全是 GHC 编译中间产物,极易触发重复加载
重启窗口比 reload window 更重要
HLS 和它拉起的 ghci 进程是长生命周期服务。你改完 stack.yaml 或 settings.json 后,只按 Ctrl+Shift+P → Developer: Reload Window 是不够的——旧 ghci 进程还在跑,新参数根本没生效。
必须:完全关闭 VSCode 窗口 → 杀掉残留进程(macOS/Linux 运行 pkill -f "ghci\|haskell-language-server",Windows 用任务管理器查 ghci.exe)→ 重新打开项目。否则你看到的还是那个吃着 1.4GB 内存、随时准备崩的旧 ghci。


















