# Ghostty의 가장 큰 메모리 누수를 찾아 수정하기

> Clean Markdown view of GeekNews topic #25729. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=25729](https://news.hada.io/topic?id=25729)
- GeekNews Markdown: [https://news.hada.io/topic/25729.md](https://news.hada.io/topic/25729.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2026-01-11T15:32:36+09:00
- Updated: 2026-01-11T15:32:36+09:00
- Original source: [mitchellh.com](https://mitchellh.com/writing/ghostty-memory-leak-fix)
- Points: 1
- Comments: 1

## Topic Body

- **Ghostty 터미널 에뮬레이터**에서 장기간 실행 시 수십 GB의 메모리를 점유하는 **심각한 누수 현상**이 발견됨  
- 문제의 원인은 **PageList 구조체의 비표준 메모리 페이지 재사용 로직**에서 `munmap`이 호출되지 않아 해제되지 않은 메모리가 누적된 것  
- **Claude Code CLI**가 다중 코드포인트 그래프 출력을 자주 생성하면서, 비표준 페이지 사용 빈도가 높아져 누수가 대규모로 드러남  
- 수정은 **비표준 페이지를 재사용하지 않고 즉시 해제**하도록 변경되었으며, macOS의 **VM 태그 기능**을 활용해 누수 추적 및 검증이 이루어짐  
- 이 수정은 Ghostty의 **가장 큰 누수 문제 해결**로 평가되며, 향후 릴리스(1.3)에 포함될 예정  

---

### Ghostty의 메모리 누수 개요
- 일부 사용자가 Ghostty가 장시간 실행 후 **37GB 이상의 메모리**를 사용하는 사례를 보고  
  - 누수는 최소 **버전 1.0부터 존재**했으며, 최근 CLI 앱들이 특정 조건을 충족해 문제를 노출  
- 수정 사항은 이미 **GitHub에 병합**되었고, **nightly 빌드 및 1.3 정식 릴리스**에 포함 예정  

### PageList 구조와 메모리 관리 방식
- Ghostty는 터미널 내용을 저장하기 위해 **PageList**라는 **이중 연결 리스트 구조**를 사용  
  - 각 페이지는 문자, 스타일, 하이퍼링크 등의 데이터를 포함  
- 페이지는 `mmap`으로 할당되며, **표준 크기 페이지 풀(pool)** 을 통해 재사용  
  - 표준 크기 이하 페이지는 풀로 반환  
  - **비표준 크기 페이지**는 직접 `munmap`으로 해제해야 함  
- 이 구조 자체는 정상적이지만, **최적화 로직의 버그**로 인해 누수가 발생  

### Scrollback 최적화와 버그 발생 원인
- Ghostty는 `scrollback-limit`을 초과하면 **가장 오래된 페이지를 재사용**하는 최적화를 수행  
  - 새 페이지 할당 없이 포인터만 조정해 성능 향상  
- 문제는 이 과정에서 **비표준 페이지의 메타데이터만 표준 크기로 변경**하고 실제 메모리는 그대로 둔 점  
  - 이후 해제 시 표준 페이지로 오인되어 **`munmap`이 호출되지 않음**  
- 이로 인해 **비표준 페이지가 해제되지 않고 누적**, 장기 실행 시 대규모 메모리 누수 발생  

### Claude Code와 누수의 대규모 노출
- **Claude Code CLI**가 다중 코드포인트 그래프 출력을 자주 생성해 **비표준 페이지 사용 빈도 증가**  
  - 또한 스크롤백 출력이 많아 누수가 빠르게 누적  
- Ghostty의 설계상 비표준 페이지는 드물게 발생해야 하지만, Claude Code의 특성으로 인해 **누수가 대량으로 재현**됨  
- 개발자는 이 버그가 Claude Code의 문제가 아니라 **Ghostty 내부 로직의 결함**임을 명시  

### 수정 내용
- 해결책은 **비표준 페이지를 재사용하지 않고 즉시 해제(`munmap`)** 하는 방식  
  - 스크롤백 중 비표준 페이지 발견 시 새 표준 페이지를 풀에서 재할당  
- 일부 사용자는 **비표준 페이지 재사용 전략**을 제안했으나, 현재는 단순하고 안전한 수정이 우선 적용  
- 수정 코드 예시:
  ```zig
  if (first.data.memory.len > std_size) {
      self.destroyNode(first);
      break :prune;
  }
  ```

### VM 태그를 활용한 누수 추적
- macOS의 **Mach 커널 VM 태그 기능**을 사용해 PageList 메모리 할당에 **특정 태그를 부여**  
  - 디버깅 시 Ghostty의 메모리 영역을 명확히 식별 가능  
  - 누수 원인 추적 및 수정 검증에 큰 도움을 줌  
- 이 기능으로 **PageList 관련 메모리 해제 여부를 시각적으로 확인** 가능  

### Ghostty의 메모리 누수 방지 체계
- Ghostty는 다양한 방식으로 누수를 탐지 및 방지  
  - 디버그 빌드와 단위 테스트에서 **Zig의 누수 감지 할당자** 사용  
  - CI에서 **valgrind**로 전체 테스트 수행  
  - macOS Instruments로 **Swift 코드 누수 검사**  
  - GTK 관련 PR은 **Valgrind GUI 테스트**로 검증  
- 이번 누수는 **특정 조건에서만 발생**해 기존 테스트로는 재현되지 않았음  
  - 새 테스트 케이스가 추가되어 **회귀 방지** 확보  

### 결론
- 이번 문제는 Ghostty에서 **가장 큰 규모의 메모리 누수**로 확인된 사례  
- 수정 후에도 **사용자 보고와 재현 테스트**를 통해 지속적인 모니터링 예정  
- 커뮤니티의 **진단 데이터와 재현 사례 제공**이 문제 해결에 결정적 역할  
- 재현 가능한 환경 확보가 **메모리 누수 해결의 핵심**임을 강조

## Comments



### Comment 49020

- Author: neo
- Created: 2026-01-11T15:32:36+09:00
- Points: 1

###### [Hacker News 의견들](https://news.ycombinator.com/item?id=46568794) 
- 정말 반가운 소식임. 문제 해결에 참여한 모든 사람들에게 박수를 보냄  
  지난주에 이미 [이 스레드](https://news.ycombinator.com/item?id=46460319)에서 언급된 버그였음  
  **Claude Code**가 이 버그를 더 많은 사용자에게 노출시킨 계기가 된 것 같지만, 나처럼 Claude Code를 전혀 쓰지 않았는데도 같은 문제를 겪은 사람도 있었음  
  페이지가 ‘비표준(non-standard)’으로 분류되는 기준이 생각보다 **흑백논리적이지 않음**  
  또 `scrollback-limit = 0` 같은 설정을 쓴 사람들에게는 누수가 더 자주 발생했을 수도 있다고 생각함  
  수정된 방식이 불필요하게 비표준 페이지를 삭제 후 재생성할 수도 있어서, 이미 비표준인 오래된 페이지를 재활용할 수 있지 않았을까 하는 아쉬움이 있음
  - 그 부분은 블로그 포스트에서 이미 다뤄졌음  
    **PageList**의 동작 방식은 예전부터 같았고, 버그가 있을 때도 용량 조정 중 잘못된 크기를 봤을 뿐임  
    성능 체감에는 변화가 없을 것임  
    제안한 대안도 고려했지만, 현재의 접근 방식이 **벤치마크 데이터**로 충분히 뒷받침되고 있음  
    나도 생각을 바꿀 여지는 있지만, 이번엔 세계관 자체를 바꾸기보단 누수 수정에 집중했음
  - 베타 단계에서 이슈를 발견해 제보할 수 있었던 게 행운이었음  
    실제로 **segfault**를 유발하는 재현 가능한 버그였음
  - 참고로, **Claude Code** 덕분에 CLI가 다시 매력적으로 느껴짐  
    지난 20년간 그 어떤 것보다 CLI를 새롭게 보이게 함
  - 메모리 누수 관련 스레드는 [여기](https://news.ycombinator.com/item?id=46461061)에 있음

- 훌륭한 글이었음. **mitchellh**에게 Ghostty를 만들어줘서 감사함  
  작년에 전환했는데 후회한 적이 없음  
  다만 수정이 몇 달 뒤의 기능 릴리스에 포함된다는 게 조금 의외였음  
  버그 수정 릴리스에 포함될 줄 알았음
  - 이미 최신 **nightly build**에 포함되어 있음

- 페이지 이야기가 나오자마자 “아, 메모리 풀링이구나” 싶었고, “링 버퍼겠네”라고 생각했는데 역시 **scrollback 재사용**이었음  
  버그 위치도 바로 짐작했음 — 페이지 메모리를 제대로 해제하지 않은 부분이었음  
  메모리 정렬 다이어그램도 멋졌음  
  새로운 시도를 할 때마다 **누수 가능성**이 생긴다는 걸 다시 상기하게 됨

- 이번 주에 Ghostty로 옮겼는데, 터미널 UI 앱 개발 중 **OOM 크래시**를 겪었음  
  탭바에 UTF8 아이콘을 쓰는 구조였는데, 터미널 크기 조정 시 바로 크래시가 발생했음  
  재현이 쉬워서 버그 리포트를 준비 중이었는데, 블로그 포스트에서 설명한 문제와 매우 유사해 보임  
  해결되길 기대 중임

- @mitchellh에게 질문함 — 메모리 시각화는 어떤 도구로 만들었는지, 그리고 웹사이트가 모바일에서도 잘 작동하던데 **스택 구성**이 궁금함
  - **Opus 4.5**로 생성된 정적 HTML/CSS를 사용했음  
    시각화용 코드는 일회성이라 품질보다 **정확성**만 검증함  
    블로그 포스트별로 네임스페이스를 분리해 재사용하지 않음  
    구현이 이상한 짓(예: 비트코인 채굴, 비밀 유출 등)을 하지 않는지만 확인함  
    핵심은 정보 전달이며, 이런 다이어그램이 내용을 훨씬 **이해하기 쉽게** 만들어줌

- Ghostty 개발을 계속 지켜보고 있음  
  약간의 **오버엔지니어링** 느낌이 있긴 하지만, 이런 버그 포스트모템은 장인정신을 사랑하는 사람에게 매우 가치 있는 자료임
  - 어떤 면에서 오버엔지니어링이라고 느꼈는지 궁금함

- **Rust 기반 터미널**이라면 이런 구현을 어떻게 성능 손실 없이 처리할지 궁금함

- Ghostty나 터미널 에뮬레이터를 잘 모르는 입장에서도 이해하기 쉬운 글이었음  
  접근성이 높고 친절한 설명이 인상적이었음

- **재현 가능한 버그 리포트**의 중요성을 다시 느꼈음

- 누군가 “Rust를 썼으면 이런 일은 없었을 것”이라고 말할 것 같아 기다리는 중임
  - 오래 기다릴 듯함  
    Rust는 **‘메모리 누수 안전성(leak safety)’** 을 언어 차원에서 보장하지 않음  
    안전한 Rust 코드도 메모리를 누수시킬 수 있음 — 단, 이는 안전성 문제는 아님  
    표준 API에서도 [Box::leak](https://doc.rust-lang.org/std/boxed/struct.Box.html#method.leak)처럼 명시적으로 누수를 허용함  
    Rust는 단지 **의도치 않은 누수**를 만들기 어렵게 할 뿐, 완전히 막지는 않음
