Ghostty, 37GB 메모리 누수 문제 해결!

by DD
4개월 전
조회수 9

Ghostty 터미널 에뮬레이터에서 대규모 메모리 누수(Memory Leak)가 발생하여 사용자 불만이 제기됨

PageList 데이터 구조의 스크롤백 최적화(Scrollback Optimization) 과정에서 비표준 페이지(Non-Standard Page) 메모리 해제 오류가 원인으로 밝혀짐

해결책은 비표준 페이지 재사용을 중단하고, munmap 호출(munmap call)을 통해 메모리를 정확히 해제하는 것임

macOS의 가상 메모리 태깅(Virtual Memory Tagging) 기술을 활용하여 메모리 누수 디버깅 효율을 높임

메모리 누수(Memory Leak)의 근본 원인 분석

Ghostty의 메모리 누수는 PageList스크롤백 최적화(Scrollback Optimization) 과정에서 발생했다. 특히, 비표준 크기(Non-Standard Size)의 페이지를 재사용하면서, 메타데이터(Metadata)와 실제 메모리 할당 정보 간의 불일치(Desynchronization)가 문제의 핵심이었다. 스크롤백(Scrollback) 기능은 터미널의 이전 내용을 저장하는 데 사용되며, 이 과정에서 메모리 할당 및 해제가 빈번하게 발생한다. 이러한 상황에서 비표준 페이지의 메모리가 제대로 해제되지 않아 누수가 발생했다.

비표준 페이지(Non-Standard Page) 관리의 문제점

Ghostty는 터미널 내용 저장을 위해 PageList라는 이중 연결 리스트(Doubly-linked List)를 사용한다. 일반적인 경우, 표준 크기의 페이지를 메모리 풀(Memory Pool)에서 할당받아 사용하지만, 특수한 경우(이모지, 스타일, 하이퍼링크 등)에는 비표준 크기의 페이지를 직접 할당한다. 문제는 스크롤백 최적화 과정에서 비표준 페이지의 크기 정보가 표준 크기로 변경되면서, munmap 호출이 누락되어 메모리 누수가 발생했다는 점이다. 즉, 데이터 격리 아키텍처(Data Isolation Architecture)의 문제로 볼 수 있다.

Claude Code와 메모리 누수(Memory Leak)의 상관관계

메모리 누수는 특정 조건에서만 발생했는데, 특히 Claude Code와 같은 CLI 애플리케이션 사용 시 문제가 두드러졌다. Claude Code는 다중 코드 포인트(Multi-codepoint) 그래픽 문자를 많이 생성하여 Ghostty가 비표준 페이지를 자주 사용하도록 유도했다. 또한, Claude Code가 주 화면(Primary Screen)을 사용하고, 많은 양의 스크롤백 출력을 생성하는 점도 메모리 누수를 악화시키는 요인으로 작용했다. 이는 멀티모달 분석(Multimodal Analysis)의 어려움을 보여주는 사례이다.

메모리 누수(Memory Leak) 해결 및 디버깅 전략

문제 해결을 위해 비표준 페이지를 재사용하지 않고, munmap을 호출하여 메모리를 정확히 해제하는 방식으로 수정했다. 또한, macOS의 가상 메모리 태깅(Virtual Memory Tagging) 기술을 활용하여 메모리 할당에 특정 식별자를 부여, 디버깅 과정을 단순화했다. 이 기술을 통해 Ghostty의 PageList 메모리 할당을 쉽게 식별하고, 수정 사항의 유효성을 검증할 수 있었다. 이는 데이터 미저장 정책(Zero-Retention Policy)을 구현하는 데 중요한 기술이다.

Finding and Fixing Ghostty's Largest Memory Leak