기억의 단편화

742025년 09월 08일5

컴포지터 팀과의 협력을 통해 색상 정확도 문제를 해결한 드미트리는, 이제 WebGPU가 브라우저라는 도시의 다른 구성원들과 평화롭게 공존하고 있다고 믿었다. 하지만 그 평화 아래에는, 훨씬 더 교활하고 감지하기 어려운 문제가 조용히 자라나고 있었다.

문제의 징후는 크롬의 ‘메모리 관리자(Memory Manager)’ 팀으로부터 시작되었다.
그들은 최근 들어, 브라우저가 시스템 메모리가 부족한 상황에서 특정 탭의 메모리를 회수(Reclaim)하는 데 실패하는 경우가 늘고 있다는 보고를 받았다. 그리고 그 실패 사례의 대부분은, WebGPU를 활발하게 사용하는 웹 애플리케이션에서 발생하고 있었다.

메모리 관리팀의 리더, 오웬이 드미트리를 찾아왔다.
“드미트리, 당신 팀의 도움이 필요합니다. 저희는 지금 유령을 쫓고 있는 기분입니다.”

오웬이 설명하는 현상은 기묘했다.
“저희 시스템은 메모리가 부족해지면, 현재 사용자가 보고 있지 않은 백그라운드 탭의 메모리를 압축하거나 디스크로 내려놓습니다. 그런데 WebGPU 탭의 경우, 이 과정이 종종 실패하거나, 엄청나게 오랜 시간이 걸립니다. 마치 무언가가 메모리를 꽉 붙잡고 놔주지 않는 것 같습니다.”

그는 당혹스러운 표정으로 말했다.
“이상한 점은, 저희가 보는 자바스크립트 힙 메모리 사용량은 그렇게 높지 않다는 겁니다. 문제는 보이지 않는 곳에 있습니다.”

드미트리는 즉시 문제의 심각성을 알아차렸다. 이것은 ‘GPU 메모리’와 관련된 문제였다.
그는 오웬에게 WebGPU의 자원 관리 모델을 설명해주었다. 개발자가 명시적으로 destroy()를 호출하지 않으면, GPU 메모리는 해제되지 않는다는 사실을.

오웬이 되물었다.
“그렇다면, 저희 메모리 관리자가 탭을 비활성화시킬 때, 그 탭이 사용하던 모든 GPU 자원을 강제로 destroy() 시켜주면 되지 않을까요?”

“그렇게 간단하지 않습니다.”
드미트리가 고개를 저었다.
“만약 개발자가 그 자원을 나중에 다시 사용하려고 참조를 가지고 있다면, 강제로 파괴된 자원에 접근하려다 애플리케이션이 크래시될 수 있습니다. 우리는 개발자의 의도를 존중해야 합니다.”

두 팀은 공동으로 이 ‘보이지 않는 메모리’의 정체를 추적하기 시작했다.
그들은 메모리 사용량이 비정상적으로 높은 WebGPU 애플리케이션들을 분석했다. 그리고 하나의 공통적인 패턴을 발견했다.

문제의 애플리케이션들은 모두, 수많은 작은 버퍼와 텍스처를 끊임없이 생성하고 있었다. 그리고 사용하지 않는 자원들을 destroy() 하기는 했지만, 그 시점이 명확하지 않았다.

드미트리는 Dawn의 저수준 메모리 할당자를 들여다보았다. 그리고 그는 문제의 근본적인 원인을 발견했다.
‘메모리 단편화(Memory Fragmentation)’.

그는 오웬에게 그림을 그려가며 설명했다.
“GPU 메모리는 거대한 땅과 같습니다. 우리가 버퍼를 하나 생성하면, 메모리 할당자는 이 땅의 일부를 잘라내어 우리에게 줍니다. 그리고 우리가 destroy()를 호출하면, 우리는 그 땅을 반납하죠.”

“문제는, 이 과정이 수천, 수만 번 반복되면서 발생합니다. 작은 땅 조각들이 계속해서 할당되었다가 반납되기를 반복하면, 전체 땅은 수많은 작은 빈 공간들로 조각나 버립니다. 마치 스위스 치즈처럼요. 결국, 전체적으로는 여유 공간이 충분히 남아있음에도 불구하고, 우리가 원하는 크기의 ‘연속된’ 땅 조각을 찾지 못해 새로운 메모리 할당에 실패하게 되는 겁니다.”

이 단편화된 메모리 구조는, 브라우저의 메모리 관리자가 탭의 상태를 효율적으로 압축하거나 저장하는 것을 극도로 어렵게 만들고 있었다.

이것은 Dawn의 버그가 아니었다. 모든 고성능 그래픽스 시스템이 안고 있는 고전적인 문제였다. 하지만 웹이라는, 자원 제약이 훨씬 심한 환경에서는 그 문제가 더욱 치명적으로 다가왔다.

해결책은 무엇인가?
드미트리와 오웬은 몇 날 며칠을 함께 고민했다.
단편화를 완전히 막을 수는 없었다. 하지만 그것을 ‘관리’할 수는 있었다.

드미트리는 새로운 아이디어를 제시했다.
“우리가 직접 메모리 할당자가 되는 겁니다. Dawn이 시작될 때, GPU로부터 아주 거대한 메모리 덩어리(Memory Heap) 몇 개를 미리 할당받습니다. 그리고 그 이후의 모든 작은 버퍼와 텍스처 생성 요청은, 우리가 직접 관리하는 이 힙 안에서 처리하는 거죠. 일종의 ‘가상 메모리 시스템’을 Dawn 내부에 구축하는 겁니다.”

이 방식, 즉 ‘사용자 정의 할당자(Custom Allocator)’를 사용하면, Dawn은 메모리 단편화를 최소화하는 방식으로 자원을 배치하고, 메모리 관리자와 더 효율적으로 소통할 수 있게 된다. 예를 들어, 브라우저가 메모리 회수를 요청하면, Dawn은 현재 사용 중인 힙의 내용을 다른 곳으로 잠시 옮겨두고, 힙 전체를 통째로 반납할 수 있었다.

이것은 Dawn의 메모리 관리 시스템을 완전히 재설계해야 하는, 엄청난 대수술이었다.
하지만 드미트리는 이것이 WebGPU가 웹 플랫폼의 ‘선량한 시민’으로 살아가기 위해 반드시 치러야 할 대가임을 알았다.

그는 오웬에게 약속했다.
“시간이 걸릴 겁니다. 하지만 우리는 이 문제를 해결할 겁니다. WebGPU가 브라우저 전체의 안정성을 위협하는 악당이 되게 놔두지는 않을 겁니다.”

그의 약속은, 단순히 다른 팀을 돕겠다는 것을 넘어선 선언이었다.
그것은 자신이 만든 기술이 낳은 모든 결과에 대해 끝까지 책임을 지겠다는, 플랫폼의 창조자로서의 무거운 맹세였다. 그는 이제, 기억의 단편들을 모아, 더 견고하고 질서 있는 세계를 재건하는 새로운 도전에 나서고 있었다.