월드를 바꿀 때마다 쌓이던 지형 재질

같은 월드로 돌아와도 재질이 늘었습니다
LAST37N의 월드 전환을 반복하자 화면은 비슷한데 Material 수가 계속 증가했습니다. 청크가 처음 로드되며 캐시가 채워지는 증가인지, 반복할 때마다 새 자산이 남는 문제인지 구분하기 위해 워밍업 이후 같은 월드의 수치를 비교했습니다. 한 번 입장한 화면만으로는 확인하기 어려운 문제였습니다.
시험은 고정 월드에 WebSocket 피어 99개를 연결한 상태에서 실제 Unity 브라우저 하나가 세 월드를 오가는 방식입니다. 월드별 최초 두 번은 이동하고 매 세 번 반복마다 연결을 끊어 복구했습니다. 이는 100개의 Unity 화면을 동시에 렌더한 시험은 아닙니다.

오브젝트를 없애도 만든 재질은 남았습니다
최초 약 10분, 99회 전환의 표본에서 crowd 월드 재질은 843개에서 1,293개로 450개 늘었습니다. 메시 수는 1,295개로 유지됐습니다. 모든 캐시가 안정적이라고 판단하지 않고 이 전체 실행을 실패 결과로 보존했습니다.
원인은 GeographicWorld.Load가 지형 영역마다 Make(new Color(...))를 호출하고 매번 새 Material을 만드는 데 있었습니다. 해당 청크의 수역 다섯 개와 반복당 증가량이 맞았습니다. 지형 GameObject를 파괴하는 것만으로 생성한 공유 재질의 소유권까지 정리되지는 않았습니다.
아래는 확인된 원인과 수정 범위를 요약한 도표입니다. 메모리 관리 코드 전체를 재현한 구현 예시는 아닙니다.
flowchart TD
A["지형 영역 로드"] --> B["같은 Color인지 확인"]
B --> C["인스턴스 안에서 재질 공유"]
D["CityScenery 파괴"] --> E["소유 재질과 Font 구독 정리"]
공유할 것과 해제할 것을 나눴습니다
동일 Color의 지형 재질은 GeographicWorld 인스턴스 안에서 공유하게 했습니다. CityScenery가 소유한 지형·벽·폰트·화재·연기 재질과 Font 구독은 OnDestroy에서 정리합니다. 기존 공유 캐릭터 캐시는 별도로 유지해 무관한 자산까지 함께 없애지 않도록 했습니다.
실제 Unity 검사에서는 두 색으로 1,002번 호출해도 재질이 두 개만 생성됐습니다. 이 작은 검사는 생성 규칙을 확인하는 근거이며, 긴 월드 전환 시험을 대신하지는 않았습니다. 이어 같은 반복 시나리오를 끝까지 다시 실행했습니다.
수정 뒤에도 같은 시간과 전환 횟수를 확인했습니다
수정 후 약 10분 동안 99회 전환과 11회 재접속을 수행했습니다. crowd 재질은 795개, 메시는 1,291개로 유지됐고 다른 월드의 재질은 794개에서 795개였습니다. 추적 할당 증가 최대치는 1,140,329바이트였으며 카메라는 하나, 최대 캐릭터는 115개, 오류는 0개였습니다.
원문 작성 당시 추가 한 시간 관찰은 진행 중이었습니다. 따라서 이 글의 수정 검증 범위는 완료된 10분 시험으로 구분합니다. 전체 브라우저나 GPU 메모리, 모바일 성능까지 해결됐다고 말하지 않습니다. 객체 수가 유지된 결과와 메모리 전체가 누수 없이 안정적이라는 결론은 같은 의미가 아니므로, 어느 자원을 누가 만들고 언제 정리하는지를 계속 확인해야 합니다.
미로


댓글
이 글에 대한 생각을 남겨 주세요.