**Three.js에서 자원 해제(Dispose)가 필수적인 이유** 웹 브라우저의 자바스크립트 엔진은 힙(Heap) 메모리에 대해 가비지 컬렉션(GC)을 수행하지만, **Three.js가 사용하는 GPU 자원(VRAM에 업로드된 기하구조, 재질, 텍스처 등)은 자동으로 가비지 컬렉션되지 않습니다**. 따라서 사용이 끝난 3D 객체와 관련 자원을 명시적으로 해제하지 않으면 런타임 내내 메모리에 남아 심각한 메모리 누수(Memory Leak)를 유발하게 됩니다. 효율적인 메모리 관리를 위해 반드시 해제해야 하는 자원과 그 방법은 다음과 같습니다. ### 1. 기본 자원 해제 (Geometries, Materials, Textures) 객체를 씬(Scene)에서 제거하는 것(`scene.remove(mesh)`)만으로는 GPU 메모리가 비워지지 않습니다. 사용이 끝난 메시(Mesh)를 처리할 때는 구성 요소 각각에 대해 **`.dispose()` 메서드를 명시적으로 호출**해야 합니다. - `mesh.geometry.dispose()` - `material.dispose()` (배열 형태의 다중 재질인 경우 순회하며 개별적으로 해제해야 합니다) - `texture.dispose()` 단일 4K 텍스처 하나가 **64MB 이상의 VRAM을 낭비**할 수 있으므로, 텍스처 자원은 더 이상 필요하지 않을 때 즉시 해제하는 것이 매우 중요합니다. ### 2. GLTF/GLB 모델의 ImageBitmap 특수 처리 일반적인 텍스처와 달리, GLTF 모델을 통해 로드된 텍스처는 내부적으로 `ImageBitmap` 형태로 메모리에 올라갑니다. 이 경우 `.dispose()`만으로는 완전히 해제되지 않으므로, **반드시 `.close()` 메서드를 명시적으로 호출**하여 누수를 막아야 합니다. ``` texture.source.data.close?.(); texture.dispose(); ``` ### 3. 렌더 타겟 (Render Targets) 해제 포스트 프로세싱(Post-processing)이나 동적 텍스처 생성을 위해 사용하는 렌더 타겟 역시 자체적으로 프레임버퍼 메모리를 할당받습니다. 효과 적용이 끝났거나 더 이상 사용하지 않는 렌더 타겟도 잊지 말고 `renderTarget.dispose()`를 호출해 해제해야 합니다. ### 4. React Three Fiber (R3F) 환경에서의 클린업 React 환경인 R3F에서 개발할 때는, 3D 객체를 렌더링하는 컴포넌트가 화면에서 사라질 때(Unmount) 자원이 해제될 수 있도록 **`useEffect`의 클린업(Cleanup) 함수 내부에서 dispose를 처리**해야 합니다. ``` useEffect(() => { return () => { geometry.dispose(); material.dispose(); texture.dispose(); }; }, []); ``` ### 5. 누수 모니터링 방법 Three.js가 제공하는 **`renderer.info.memory`** 객체를 콘솔에 출력하거나 감시하면 현재 GPU에 올라간 지오메트리(`geometries`)와 텍스처(`textures`)의 개수를 실시간으로 확인할 수 있습니다. 이 숫자가 일정하게 유지되지 않고 씬 전환 시마다 계속 증가한다면 메모리 누수가 발생하고 있다는 확실한 증거이므로 누수 지점을 찾아 디버깅해야 합니다.