概要
Ghosttyで発生していた大規模なメモリリークの原因と修正内容の解説。 メモリ管理の仕組みと、バグが発生した経緯の説明。 Claude Codeを契機にリークが顕在化した背景。 修正方法と今後の対策についての考察。 再発防止策やコミュニティの貢献への謝辞。
Ghosttyのメモリリーク問題と修正
- 数ヶ月前から Ghostty で極端な メモリ消費 の報告が相次いだ事例。
- 一部ユーザーが 10日間の稼働で37GB 消費を確認。
- 本件の 原因究明 と 修正内容 の概要説明。
- Ghostty 1.0以降 から存在したバグだが、 Claude Code などのCLIアプリにより顕在化。
- 修正済み であり、 nightlyリリース や 1.3タグ にて提供予定。
Ghosttyのメモリ管理構造
- PageList というデータ構造で端末内容を管理。
- PageList は双方向リンクリストで、各ノードがページ(文字・スタイル・ハイパーリンク等)を保持。
- ページは 標準サイズ と 非標準サイズ の2種類。
- 標準ページ :プールから取得・解放時はプールに戻す
- 非標準ページ :直接mmapで確保・解放時はmunmap呼び出し
- mmap の頻繁な呼び出しを避けるため、 メモリプール を活用。
スクロールバック最適化とバグの発生
- スクロールバック制限 に達すると、最古のページを再利用する最適化を実装。
- 再利用時、メタデータのみ標準サイズにリセットし、実際のメモリは非標準のまま残存。
- 解放時、標準ページと誤認し munmap が呼ばれず、 メモリリーク 発生。
- 非標準ページ は本来稀だが、Claude Codeの出力仕様で大量発生。
修正内容
- 非標準ページ は再利用せず、解放時に必ず munmap を実行。
- スクロールバック時に非標準ページを検出した場合は、 新規標準ページ をプールから取得。
- macOS向けに 仮想メモリタグ を導入し、PageListのメモリを特定しやすく改善。
再発防止策
- Zigのリーク検出アロケータ をデバッグビルド・ユニットテストで利用。
- Valgrind や macOS Instruments でGUIやGTKパスも検証。
- 今回のリーク再現用のテストケースを新規追加。
- 再現性のあるバグ報告が修正の鍵。
コミュニティへの謝辞
- @grishy による再現手順の提供と分析への感謝。
- 詳細な診断を行ったコミュニティメンバーへの謝意。
- PageList が問題箇所であることを特定するための重要なヒントの提供。
Ghosttyの今後のメモリ管理戦略
- 現在は 標準ページ を基本とし、最適化・単純化を優先。
- 非標準ページ の再利用や動的調整は今後の課題として検討。
- より複雑な戦略(利用頻度に応じた調整等)は追加調査後に検討予定。
まとめ
- Ghostty史上最大級のメモリリーク が修正された事例。
- 今後も メモリ関連の報告 を注視し、再現性のある問題には迅速に対応予定。
- コミュニティの協力がバグ修正の大きな原動力となった事例。