Unity 검색

Game creators testing game design, features in creative office space using PC with two monitors.
Game creators testing game design, features in creative office space using PC with two monitors.
공유

Is this article helpful for you?

Thank you for your feedback!

효율적으로 메모리 문제를 감지하고 성능을 최적화하는 데 있어 핵심은 바로 Memory Profiler에 표시되는 정보와 해당 정보의 정밀도입니다. 유니티는 이 분야에 상당한 노력을 기울이고 있습니다. 최근에 포스팅된 두 개의 블로그에서 저희 팀은 Memory Profiler 1.0.0을 소개하고 게임의 메모리 관련 문제를 진단, 검사하기 위한 5가지 주요 워크플로를 살펴보았습니다.

조만간 Memory Profiler 1.1을 출시할 예정이며(실험 버전은 지금 사용 가능) 이 버전에는 메모리가 어떻게 작동하는지, 그리고 애플리케이션 메모리 사용량이 어떻게 계산되는지에 대한 레이블과 설명이 업데이트되어 제공됩니다.

개발자들과 대화해 보면 이들은 늘 메모리 사용량에 신경을 쓰고 있습니다. 따라서 이 포스팅에서는 자주 묻는 질문에 답변하면서 다음 세 가지 주제를 중점적으로 다루려 합니다.

  • 상주 메모리의 정의
  • 애플리케이션 메모리 사용량이 계산되는 방식
  • 메모리 사용량을 분석하는 방법

상주 메모리의 정의

Unity의 메모리 할당을 자세히 살펴보겠습니다. 엔진에서 메모리를 할당할 때 엔진은 요청된 할당에 맞는 가상 주소 공간에서 먼저 여러 메모리 페이지를 예약합니다. 이때 페이지는 메모리 관리의 최소 단위입니다. 가상 주소 공간과 물리적 스토리지는 각각 여러 페이지로 구성되며, 페이지 크기는 사용되는 플랫폼에 따라 달라집니다. 예를 들어 x86 컴퓨터에서는 페이지 크기가 4KB입니다.

페이지를 충분히 예약하고 나면 엔진은 물리적 스토리지를 메모리에 '커밋'하도록 OS(운영체제)에 요청합니다. 이것이 바로 할당된 메모리를 흔히 '커밋됨'이라고 표현하는 이유입니다. 다음으로 OS는 이제 페이지에 물리적 스토리지가 할당되었으며 액세스도 가능하다고 등록합니다. 그러면 애플리케이션에서 보고한 '총 커밋된 메모리'가 늘어납니다. 하지만 애플리케이션의 물리적 메모리 사용량은 그대로입니다.

Graphic depiction of reserved pages | Memory Profiler deep dive

사용량이 그대로인 이유는 영역을 물리적 스토리지에 커밋했어도 대부분의 OS에는 지연이 발생하며 절약하는 성질이 있어 특정 물리적 스토리지 위치가 할당되지 않았기 때문입니다. 예를 들어 커밋된 영역에 무언가를 쓰려 한다고 가정해 보겠습니다. 영역 아래에 아직 물리적 메모리가 없기 때문에 영역에 액세스하면 페이지 오류가 발생합니다. 이에 대응하여 OS의 메모리 관리자는 작업을 완료할 수 있도록 이전에 사용 가능했던 물리적 페이지를 할당합니다. 모든 작업이 페이지 크기 세분화를 통해 수행되기 때문에 영역에서 액세스되지 않는 페이지는 빈 상태로 유지되고 물리적 메모리가 할당되지 않습니다. 이와 유사하게 애플리케이션의 상주 메모리 크기는 작업을 완료하기 위해 할당된 모든 물리적 메모리 페이지의 총 크기만큼 늘어납니다.

Graphic depiction of committed pages | Memory Profiler deep dive

한동안 페이지가 액세스되지 않거나 물리적 메모리에 대한 수요가 높은 경우, OS는 플랫폼에서 지원되는 사항에 따라 할당된 영역의 페이지 일부를 압축 메모리나 페이지 스왑 파일로 오프로드할 수 있습니다.

Graphic depiction of swapped pages | Memory Profiler deep dive

이 경우 애플리케이션에서 보고한 할당된 메모리는 그대로 유지되지만 상주 메모리 크기는 줄어듭니다.

애플리케이션 메모리 사용량이 계산되는 방식

이미 눈치채셨을 수도 있지만, 할당된 메모리만 확인하면 어떤 할당에서 물리적 메모리를 소비하는지 잘못 판단하여 문제가 없는 항목을 최적화하는 오류가 발생할 수 있습니다. 그러면 소중한 시간을 낭비하게 될 뿐만 아니라 애플리케이션 성능과 안정성을 개선하기도 어려워집니다.

전반적으로 애플리케이션 메모리 상태는 아래 다이어그램으로 설명할 수 있습니다.

Diagram of application memory state

요약하자면 메모리 사용량이 계산되는 방식은 다음과 같습니다.

물리적 메모리 사용량 = 애플리케이션 상주 메모리 + 애플리케이션 압축 메모리 페이지

메모리 사용량 분석

Memory Profiler 1.1의 Summary, Unity Objects, All Of Memory 뷰에서는 할당된 메모리 크기뿐 아니라 상주 메모리에 대한 정보도 제공됩니다. 하지만 이 정보는 Memory Profiler 스냅샷이 Unity 2022.2 이상 버전으로 만들어졌을 때만 표시됩니다. 이전 버전의 스냅샷에서도 업데이트된 UI와 요약 정보 뷰는 표시되지만, 상주 메모리에 대한 정보는 표시되지 않습니다.

Summary view of Memory Profiler 1.1 in the Unity Editor

Summary 뷰에서는 일반 개요와 함께 필수 지표인 Total Resident on Device가 제공됩니다. 메모리가 제한된 플랫폼에서 애플리케이션을 실행해야 하는 경우 Total Resident on Device는 메모리 부족 경고와 메모리 고갈로 인한 강제 종료를 검토하는 데 아주 중요합니다. 일반적으로 기기에서 사용 가능한 총 물리적 메모리의 70%를 초과해서는 안 됩니다.

상세한 분석을 보려면 Unity Objects와 All of Memory 뷰를 사용하면 됩니다. 사용 중인 총 물리적 메모리를 가장 많이 차지하는 오브젝트를 확인하려면 드롭다운 메뉴에서 Resident on Device 또는 Allocated and Resident on Device를 선택하고 Resident size를 기준으로 정렬합니다.

All of Memory view for Memory Profiler 1.1 in the Unity Editor

상주 메모리 사용량을 분석할 때는 다음 사항을 기억하세요.

  • Managed 메모리는 대부분 상주 메모리입니다. Mono 힙과 Boehm 가비지 컬렉터는 주기적으로 오브젝트에 액세스하여 해당 오브젝트를 상주 메모리로 만듭니다.
  • Graphic (Estimated) 메모리는 추정치로 표시됩니다. 대부분의 플랫폼에서는 그래픽스 리소스의 정확한 위치에 대한 정보에 액세스할 수 없기 때문에 너비, 높이, 깊이, 픽셀 형식 등 사용 가능한 정보를 바탕으로 크기를 추정합니다. 이는 곧 그래픽스 리소스의 상주 상태에 대한 정보도 알 수 없다는 뜻입니다. 사용성을 위해 모든 그래픽스 오브젝트는 Allocated 뷰 모드에서만 표시됩니다.
  • Untracked는 애플리케이션에 의해 할당된 것으로 OS에서 보고하지만 할당의 소스에 대한 확실한 정보가 결여되어 있는 모든 메모리입니다. 네이티브 플러그인, OS 라이브러리, 스레드 스택 등이 여기에 포함될 수 있습니다. 일부 플랫폼의 경우 그룹 요약 정보에 어디에서 해당 메모리를 할당했을 수 있는지에 대한 분석 내용이 추가로 제공됩니다.

오브젝트에서 사용하는 모든 Unity 비관리형 할당이 포함된 Native 메모리를 분석하는 경우 Reserved 메모리 항목이 표시됩니다. 이 메모리는 Unity 메모리 관리자에 의해 할당되었으나 캡처 중에 Unity 오브젝트에서 사용하지 않는 메모리입니다. 다음은 몇 가지 유용한 정보입니다.

  • Reserved 메모리는 상주 메모리일 수 있으며, 이는 최근에 삭제된 오브젝트가 있을 수 있다는 의미입니다.
  • Memory Profiler 설정으로 이동하여 'Show reserved memory breakdown' 체크박스를 활성화하면 Reserved의 요약 사항에 대한 추가 정보를 확인할 수 있습니다. 기본적으로 이 체크박스는 비활성화되어 있습니다. Reserved의 요약 사항에 유용한 정보가 항상 충분히 포함되는 것은 아니며, 이 정보를 활용하려면 Unity 메모리 관리자의 작동 방식을 심층적으로 이해해야 하기 때문입니다.
  • 할당자 설정 기술 자료에서 Unity 메모리 관리자와 할당 전략을 자세히 알아볼 수 있습니다.

일부 플랫폼에서는 크기가 큰 경우 플랫폼별 그룹이 추가로 표시됩니다. Android의 Android Runtime을 예로 들 수 있으며, 다음은 Android Runtime에 대한 몇 가지 참고 사항입니다.

  • 일부 버전에서 Android Runtime은 상당한 양의 메모리를 사전 할당하는 경향이 있으나 이를 사용하지는 않습니다. 이 경우 할당된 메모리는 애플리케이션 메모리 사용량에 추가되지 않으며, 상주 부분만 고려해야 합니다.
  • Android Runtime의 상주 부분이 많은 양의 애플리케이션 메모리 사용량을 차지하는 경우 Android Studio 프로파일러를 사용하여 Java로 수행된 할당을 분석합니다.
  • Android에는 기본적으로 페이지 파일이나 메모리 압축이 없지만, Linux 커널은 애플리케이션에 많은 커밋을 허용하며 이로 인해 물리적으로 사용 가능한 것보다 많은 메모리를 할당할 수도 있습니다.
  • 캡처할 때는 사용 중인 기기를 파악해야 합니다. 일부 벤더는 Android Linux 커널에 메모리 압축(zRAM) 또는 벤더 커스텀 페이지 스왑 파일 툴을 제공합니다.

결론

이 포스팅에서는 Memory Profiler 1.1(실험 버전 지금 사용 가능)에서 도입될 기능을 간략히 소개하고 메모리 사용량에 관한 여러 가지 주제를 살펴보았습니다. 이 내용이 여러분께 도움이 되었길 바랍니다.

저희 팀의 목표는 Memory Profiler를 계속 개선하여 더 정밀하고 구체적인 정보를 제공하는 동시에, 잠재적인 메모리 고갈 상황과 더불어 메모리 고갈에 얼마나 근접하였는지를 사용자에게 알리고 경고하는 것입니다. 제품 로드맵에서 진행 상황을 알아보고 의견을 들려 주세요.

포럼에 들러 피드백을 공유해 주세요. 연재 중인 Tech from the Trenches 시리즈에서 다른 유니티 개발자들의 새로운 기술 블로그도 확인할 수 있습니다.

2023년 3월 28일 엔진 & 플랫폼 | 10 분 소요

Is this article helpful for you?

Thank you for your feedback!

관련 게시물