文章摘要
文章讲述了Ghostty终端软件存在严重内存泄漏问题,用户报告运行10天后占用高达37GB内存。作者经过排查发现该漏洞自1.0版本就存在,近期因某些CLI应用(如Claude Code)触发条件才显现。文章分享了漏洞成因、Ghostty内部机制分析及修复过程,相关补丁已合并至主分支。
文章总结
发现并修复Ghostty的最大内存泄漏问题
作者:Mitchell Hashimoto
发布日期:2026年1月10日
几个月前,用户开始报告Ghostty终端占用大量内存的问题,甚至有用户反映在连续运行10天后内存占用高达37 GB。如今,这个问题已通过提交的修复方案得到解决。本文将详细介绍泄漏的原因、Ghostty的内部机制以及排查过程。
问题背景
该内存泄漏问题至少从Ghostty 1.0版本就已存在,但直到近期流行的CLI工具(如Claude Code)大规模触发特定条件时才显现。由于触发条件较为罕见,问题诊断变得尤为困难。修复已并入测试版/夜间版,并计划在3月的1.3正式版中发布。
Ghostty的内存管理机制
Ghostty使用名为PageList的双向链表管理终端内容(字符、样式、超链接等)。其核心机制包括:
1. 内存池:通过mmap分配标准大小的页面,减少频繁系统调用。
2. 非标准页面:当内容超出标准大小时,直接分配可变尺寸页面(不进入内存池)。
释放逻辑为:
- 标准页面:返回内存池复用;
- 非标准页面:调用munmap直接释放。
滚动优化与泄漏根源
Ghostty通过scrollback-limit限制历史记录,并在达到上限时复用最旧页面作为新页面(避免重复分配)。问题在于:复用非标准页面时,仅重置元数据中的尺寸为“标准大小”,而未实际调整底层内存分配。导致后续释放时误判为可复用页面,未调用munmap,造成内存泄漏。
触发条件
Claude Code的CLI工具因输出大量多码位字符,频繁触发非标准页面分配,加之其高强度的滚动输出,最终形成“完美风暴”导致泄漏量激增。
修复方案
修复策略简单直接:禁止复用非标准页面。遇到此类页面时,直接销毁并分配新标准页面。核心代码如下:
zig
if (first.data.memory.len > std_size) {
self.destroyNode(first);
break :prune;
}
泄漏检测工具增强
为便于调试,作者在macOS上引入虚拟内存标签功能,使PageList内存分配在工具中可单独标识,显著提升泄漏追踪效率。
预防措施
Ghostty团队已采取多项防泄漏措施: - 调试版本使用泄漏检测分配器; - CI流程中通过Valgrind检测未定义内存行为; - 定期用macOS Instruments检查Swift代码泄漏; - GTK相关PR需通过Valgrind全GUI测试。
此次泄漏因触发条件特殊未被现有测试覆盖,修复后已补充针对性测试用例。
致谢
特别感谢用户@grishy提供稳定复现环境,以及其他用户通过详细诊断数据(如footprint输出和VM区域统计)帮助定位问题。
注:本文内容为人工撰写,图表制作过程中虽使用AI辅助,但均经过人工校验。
评论总结
以下是评论内容的总结:
对问题修复的肯定与改进建议
- 用户肯定问题修复的价值,但也指出修复方案可能带来不必要的页面重建(评论1:"the fix will needlessly delete and recreate non-standard pages")。
- 建议其他解决方案,如内存分配标记、内存池范围检查或固定大小内存块(评论9:"leave some flag of how it was allocated";"check if the memory to be freed is within that range")。
对Ghostty的正面评价
- 用户称赞Ghostty的易用性和开发者(评论6:"Super accessible write up";评论7:"Great write-up...have not regretted it")。
对问题重现和修复时机的讨论
- 用户强调可靠重现的重要性(评论2:"Reliable reproductions are so valuable")。
- 对修复延迟到功能版本发布表示意外(评论7:"surprised that the fix is reserved for a feature release")。
具体问题反馈
- 用户报告类似的内存溢出崩溃问题(评论8:"resizing the terminal would quickly trigger the crash")。
- 提出技术改进建议,如使用循环缓冲区(评论10:"Why not just use a circular buffer for the scroll back?")。
其他讨论
- 用户询问技术细节(评论4:"what did you use for the memory visualizations?")。
- 调侃语言选择的争论(评论11:"waiting for someone to say 'this wouldn't have happen if you chose rust'")。
总结:评论普遍认可问题修复,但也提出了改进建议和疑问,同时对Ghostty表示赞赏。部分用户分享了类似问题的经历,并讨论了技术解决方案。