상위 수준 애플리케이션에서 메모리 사용

이 항목에서는 상위 수준 애플리케이션의 메모리 사용에 대한 세부 정보를 제공합니다. RTApps(실시간 지원 애플리케이션)에 사용할 수 있는 메모리에 대한 자세한 내용은 메모리 관리 및 대기 시간 고려 사항을 참조하세요.

상위 수준 애플리케이션은 다음 메모리 및 스토리지에 액세스할 수 있습니다.

  • 상위 수준 코어의 256KiB RAM으로, 대략적인 애플리케이션 사용을 위해 전적으로 예약됩니다. 이 공간의 최대 1KiB는 상위 수준 애플리케이션과 RTApps가 통신하는 각 공유 버퍼 채널에 할당될 수 있습니다.
  • 상위 수준 코어와 실시간 코어 간에 공유되는 1MiB 읽기 전용 플래시 메모리입니다.
  • 디바이스를 다시 부팅할 때 유지되는 읽기/쓰기(변경 가능한) 스토리지입니다. 변경 가능한 스토리지에 대한 자세한 내용은 Azure Sphere에서 스토리지 사용을 참조하세요.

참고

플래시를 반복적으로 업데이트하면 결국 플래시가 마모되어 유효하지 않습니다. 따라서 플래시의 불필요한 업데이트를 방지하기 위해 코드를 디자인해야 합니다. 예를 들어 다시 시작한 후 저장된 상태를 복구할 수 있도록 종료하기 전에 애플리케이션 상태를 저장하려면 상태가 변경된 경우에만 애플리케이션의 상태를 플래시에 저장하는 것이 좋습니다.

플래시 메모리 사용량 확인

플래시 메모리 사용량을 확인하려면 이미지 메타데이터, 애플리케이션 매니페스트 및 실행 파일을 포함하는 이미지 패키지 파일의 크기만 고려합니다. 주변 장치를 제어하고 Azure IoT Hub 연결을 사용하도록 설정하는 Azure Sphere OS 또는 런타임 서비스 및 공유 라이브러리와 같이 Microsoft에서 제공하는 구성 요소에 필요한 스토리지를 고려할 필요가 없습니다. 마찬가지로 애플리케이션의 전체 백업 복사본 크기 또는 장애 조치(failover) 또는 롤백을 사용하도록 설정하는 구성 요소(손상 또는 무선 업데이트 문제 발생 시)를 포함할 필요가 없습니다.

그러나 개발 및 디버깅하는 동안 디버거의 크기는 제한에 대해 계산됩니다. 디버거는 az sphere device enable-development 에 의해 자동으로 추가되고 [az sphere device enable-cloud-test](.)에 의해 제거됩니다. /reference/az sphere-device.md). Microsoft Azure Sphere SDK 설치 디렉터리의 DebugTools 폴더에서 gdbserver.imagepackage를 검색하여 SDK에서 사용하는 디버거 크기를 찾을 수 있습니다.

az sphere device sideload 명령은 애플리케이션 이미지 패키지와 디버거(있는 경우)가 1MiB 총 제한을 초과하는 경우 오류를 반환합니다. Azure Sphere 카탈로그에 새 이미지를 업로드하는 az sphere image add --image 명령은 이미지 패키지가 1MiB를 초과하는 경우에도 오류를 반환합니다.

256KiB RAM 제한은 애플리케이션에만 적용됩니다. 디버거에서 사용하는 RAM을 허용할 필요가 없습니다. 커널 할당을 위해 추가 메모리가 예약됩니다.

현재 Azure Sphere 칩(MT3620)을 위해 작성된 애플리케이션에 대해 사용 가능한 플래시 및 RAM이 증가할 수 있지만 감소하지는 않습니다. 향후 Azure Sphere 칩에는 다른 제한이 있을 수 있습니다.

메모리 부족 조건

애플리케이션에서 RAM을 너무 많이 사용하는 경우 Azure Sphere OS는 SIGKILL 신호로 종료합니다. 예를 들어 디버거에는 다음이 표시됩니다.

Child terminated with signal = 0x9 (SIGKILL)

SIGKILL 신호는 SIGTERM 요청을 받은 후 상위 수준 애플리케이션이 종료되지 않을 경우에도 발생합니다. 자세한 내용은 애플리케이션의 수명 주기를 참조하세요.

메모리 부족 조건으로 인해 애플리케이션에서 충돌을 방지하려면 상위 수준 애플리케이션에서 RAM 사용량을 관리하는 모범 사례를 참조하세요.

런타임 애플리케이션 RAM 사용량 확인

Azure Sphere는 런타임에 메모리 사용량 정보를 가져오기 위한 여러 함수를 제공합니다. 이를 사용하여 상위 수준 애플리케이션의 메모리 사용량을 모니터링하여 메모리 사용량이 256KiB 제한 내에서 지정한 임계값을 초과하는 경우 애플리케이션을 안전하게 다시 시작할 수 있습니다. 사용 가능한 함수는 다음과 같습니다.

  • Applications_GetTotalMemoryUsageInKB: 총 메모리 사용량을 키비바이트 단위로 가져옵니다. 이는 앱 또는 디버깅 서버를 대신하여 커널 할당(예: 소켓용 버퍼)을 포함하여 시스템에서 앱의 총 실제 메모리 사용량이며, 원시 값(KiB)으로 반환됩니다.
  • Applications_GetUserModeMemoryUsageInKB: 사용자 모드 메모리 사용량을 키비바이트 단위로 가져옵니다. 이는 앱에서 직접 사용하는 실제 메모리 양, 해당 라이브러리를 대신하여 사용하는 메모리( anon 할당이라고도 함) 및 디버깅 서버에서 사용하는 메모리이며, 원시 값(KiB)으로 반환됩니다.
  • Applications_GetPeakUserModeMemoryUsageInKB: 최대 사용자 모드 메모리 사용량을 키비바이트 단위로 가져옵니다. 현재 세션에서 사용되는 최대 사용자 메모리 양입니다. 애플리케이션의 메모리 사용량을 테스트할 때 이 값이 256KiB를 초과하지 않는지 확인해야 합니다. 이 값은 앱이 다시 시작되거나 다시 배포될 때마다 다시 설정됩니다. 이 함수를 사용하여 애플리케이션이 256KiB 권장 한도에 얼마나 근접하는지 대략적인 조사합니다.

상위 수준 애플리케이션에서 이러한 함수를 사용하려면 applications.h 헤더 파일을 포함합니다. 개발 중에 이러한 함수를 사용하여 애플리케이션의 전체 메모리 사용에 대한 아이디어를 얻을 수 있지만 로깅과 함께 사용하여 필드의 디바이스에서 정보를 캡처할 수도 있습니다. 메모리 남용 검색 및 정리 코드 조각은 예기치 않은 메모리 사용량을 검색하고 정상적으로 처리하는 방법을 보여 줍니다.

참고

이러한 함수는 OS에서 볼 수 있는 메모리 사용량을 반환합니다. 현재 사용자 힙에 대한 할당을 위해 애플리케이션에서 메모리를 해제하는 것은 이러한 함수에 의해 보고되지 않습니다. 나중에 사용하기 위해 메모리가 malloc 라이브러리로 반환되지만 OS 자체에서 메모리를 할당하고 해제하지 않는 한 OS에서 보고한 통계는 변경되지 않은 상태로 유지됩니다. 예를 들어 소켓에 대한 메모리를 할당하는 것이 있습니다. 따라서 이러한 함수는 애플리케이션이 최대한의 안정성을 위해 보수적으로 작동하는 데 도움이 되는 최악의 시나리오를 이해하는 데 유용합니다. 값은 근사치이며 OS 버전에 따라 다를 수 있습니다.

힙 메모리 할당 추적 추가

힙 메모리 할당 추적을 추가하여 정적 및 동적으로 연결된 라이브러리에 의해 수행되는 사용자 및 커널 할당을 보여 줍니다. 이렇게 하면 가장 효과적으로 사용할 수 있도록 애플리케이션에서 메모리를 사용하는 위치를 보다 자세히 파악할 수 있습니다. Azure Sphere OS 버전 21.07 이상 및 ARV(애플리케이션 런타임 버전) 10 이상에서 사용할 수 있는 이 기능은 개발 지원 디바이스에서만 작동하며 디버거에서 애플리케이션이 실행 되고 있지 않은 경우에만 작동합니다.

참고

힙 메모리 할당 추적이 올바르게 작동하려면 이 섹션에 설명된 구성 작업을 모두 완료해야 합니다. 이렇게 하지 않으면 컴파일 중에 경고가 보고되고 힙 메모리 정보가 표시되지 않습니다.

힙 메모리 할당 추적을 사용하도록 설정하려면 다음 두 가지 작업을 수행해야 합니다.

  • 애플리케이션의 app-manifest.json 파일에 HeapMemStats 기능을 추가합니다.

      "Capabilities": {
        "HeapMemStats": true
      },
    
  • 애플리케이션의 CMakeLists.txt 파일의 명령에 를 추가하여 libmalloc 라이브러리를 azsphere_target_add_image 이미지 패키지에 추가 DEBUG_LIB "libmalloc" 합니다.

    azsphere_target_add_image_package(${PROJECT_NAME} DEBUG_LIB "libmalloc")
    

중요

힙 메모리 할당 추적은 개발 지원 디바이스에서만 작동하므로 배포용 이미지 패키지를 빌드하기 전에 애플리케이션에서 제거하려면 다음을 수행해야 합니다.

  • 애플리케이션의 app-manifest.json 파일에서 '"HeapMemStats": true' 줄을 삭제합니다.
  • 애플리케이션의 azsphere_target_add_image_package(${PROJECT_NAME} DEBUG_LIB "libmalloc" CMakeLists.txt 파일의 명령에서 제거 DEBUG_LIB "libmalloc" 합니다.

Visual Studio 성능 프로파일러 사용

Visual Studio를 사용하는 경우 성능 프로파일러 기능을 사용하여 애플리케이션 메모리 사용에 대한 정보를 가져올 수 있습니다. 이 프로파일러를 사용하는 자습서는 Tutorials/MemoryUsage를 참조하세요.

필수 구성 요소

메모리 사용량 프로파일러 시작

  1. 성능 프로파일러디버그>를 선택하거나 Alt+F2를 눌러 성능 프로파일러 시작 창을 엽니다.

    Visual Studio 성능 프로파일러 창

  2. 분석 대상에서 Azure Sphere Device Profiler가 표시되지 않으면 대상 선택을 선택하고Azure Sphere 디바이스 프로파일러를 선택합니다.

  3. 사용 가능한 도구에서 Azure Sphere 메모리 사용량을 선택한 다음 시작을 선택하여 메모리 사용량 프로파일링 창을 열고 메모리 프로파일러를 시작합니다.

  4. 애플리케이션을 배포하거나 다시 시작해야 하는 경우 디버그>디버깅하지 않고 시작을 선택하거나 Ctrl+F5 를 눌러 디바이스에 애플리케이션을 배포합니다.

    중요

    애플리케이션에 대한 정확한 RAM 사용 정보를 얻으려면 [디버깅 하지 않고 앱을 시작](buid-hl-app.md#build-and-deploy-the-application-in- visual-studio-without-debugging)하는 것이 중요합니다. 디버깅 서버에서 사용하는 메모리가 보고된 RAM 사용량 통계에 포함되므로 디버거에서 앱을 실행하면 RAM 사용량이 증가합니다.

메모리 사용량 프로파일러 데이터 해석

메모리 사용량 프로파일링 창에는 다음과 같은 보기가 표시됩니다.

Visual Studio 메모리 사용 프로파일러 창

보기 중앙에서 Azure Sphere 디바이스 물리적 메모리 그래프는 앱이 실행되는 동안 세 개의 서로 다른 RAM 사용 통계(가장 가까운 KiB에 표시됨)를 세 개의 다른 줄로 표시합니다.

  • 총: 앱 또는 디버깅 서버를 대신하여 커널 할당(예: 소켓 버퍼)을 포함하여 시스템에서 앱의 총 실제 메모리 사용량입니다.
  • 사용자: 앱에서 직접 사용하는 실제 메모리 양, 해당 라이브러리를 대신하여 사용하는 메모리( anon 할당이라고도 함) 및 디버깅 서버에서 사용하는 메모리입니다.
  • 최고 사용자: 현재 세션에서 사용되는 최대 사용자 메모리 양입니다. 애플리케이션의 메모리 사용량을 테스트할 때 이 값이 256KiB를 초과하지 않는지 확인해야 합니다. 커널 할당을 위해 추가 메모리가 예약됩니다. 이 값은 앱이 다시 시작되거나 다시 배포될 때마다 다시 설정됩니다.

또한 그래프는 New Peak 이벤트(삼각형으로 표시됨)의 발생을 표시합니다. 이 이벤트는 최대 사용자 메모리 사용량이 새로운 최대값이 될 때마다 발생합니다. 이벤트는 화면 읽기 프로그램 접근성에 대해 사용하도록 설정됩니다.

힙 메모리 할당 추적을 사용하도록 설정했고 애플리케이션이 디버거에서 실행되고 있지 않으면 힙 메모리 통계를 보여 주는 추가 그래프가 표시됩니다.

  • 총 힙: 정적 및 동적 라이브러리를 포함하여 애플리케이션을 대신하여 할당된 총 힙 메모리입니다.
  • 공유 라이브러리 힙: Azure Sphere OS에서 제공하는 동적으로 연결된 라이브러리의 할당입니다.

Visual Studio 힙 메모리 사용량

그래프 위에서 타임라인 보기는 아래 그래프의 데이터와 상관 관계가 있는 앱의 런타임을 표시합니다. 확대축소를 사용하여 특정 기간에 집중합니다.

그래프 아래에 테이블 뷰는 동일한 메모리 통계 및 이벤트를 표시합니다.

테이블에서 클립보드로 데이터를 복사하려면 Ctrl+A 를 눌러 모든 행을 선택한 다음 Ctrl+C를 누릅니다.

이 섹션에 표시된 처음 두 그래프는 메모리 누수가 포함된 메모리 사용량 자습서의 1단계를 실행하는 동안 수행되었습니다. 메모리 사용량은 각 그래프에서 단조롭게 상승하여 누출에 대한 시각적 증거를 제공합니다. 메모리 사용 자습서의 2단계에서와 같이 누수가 수정되면 메모리가 할당되고 할당 취소될 때 그래프가 상승하고 떨어집니다.

메모리 누수가 없는 Visual Studio 힙 메모리 사용량

총 메모리 사용량에 대한 통계 보기

az sphere device app show-memory-stats 명령은 연결된 디바이스에서 실행되는 애플리케이션의 총 메모리 사용량, 사용자 모드 사용량 및 최고 사용자 모드 사용량에 대한 메모리 사용량 통계를 반환합니다. 디바이스에는 appDevelopment 디바이스 기능이 이 명령을 실행하도록 구성되어 있어야 합니다.

앱이 실행되는 동안 표시되는 RAM 사용 통계는 다음과 같습니다.

  • 합계(커널 + 사용자 모드): 앱 또는 디버깅 서버를 대신하여 커널 할당(예: 소켓 버퍼)을 포함하여 시스템에서 앱의 총 실제 메모리 사용량입니다.
  • 사용자 모드: 앱에서 직접 사용하는 실제 메모리 양, 해당 라이브러리를 대신하여 사용하는 메모리( anon 할당이라고도 함) 및 디버깅 서버에서 사용하는 메모리입니다.
  • 최대 사용자 모드: 현재 세션에서 사용되는 최대 사용자 메모리 양입니다. 애플리케이션의 메모리 사용량을 테스트할 때 이 값이 256KiB를 초과하지 않는지 확인해야 합니다. 커널 할당을 위해 추가 메모리가 예약됩니다. 이 값은 앱이 다시 시작되거나 다시 배포될 때마다 다시 설정됩니다.

힙 메모리 할당 추적을 사용하도록 설정했고 애플리케이션이 디버거에서 실행되고 있지 않으면 힙 메모리 통계의 추가 줄이 표시됩니다.

  • 힙: 앱 + 정적 라이브러리: 코드 및 정적으로 연결된 모든 라이브러리의 커널 및 사용자 할당입니다.
  • 힙: <동적 라이브러리 할당>: Azure Sphere OS에서 제공하는 개별 동적으로 연결된 라이브러리의 할당입니다.

메모리 사용량 연속 모니터링

시간이 지남에 따라 메모리 사용량을 모니터링하려면 스크립트를 사용하여 [az sphere device app show-memory-stats](.)를 실행할 수 있습니다. 다음 예제에 설명된 대로 루프의 /reference/az sphere-device.md) 명령:

Windows 명령 프롬프트

메모장 또는 다른 텍스트 편집기를 사용하여 다음 콘텐츠로 memuse.bat 일괄 처리 스크립트 파일을 만듭니다.

@echo off

:loop
call az sphere device app show-memory-stats
choice /d y /t 1 > nul
goto loop

명령 프롬프트에 이름을 입력하여 일괄 처리 스크립트를 실행합니다(또는 현재 디렉터리에 없는 경우 파일의 전체 경로).

C:\Users\username> memuse.bat
 -------------------------- -------------
 Name                       Usage (bytes)
 ========================================
 Total (Kernel + User Mode) 65536
 -------------------------- -------------
 User Mode                  36864
 -------------------------- -------------
 Peak User Mode             36864
 -------------------------- -------------
 -------------------------- -------------
 Name                       Usage (bytes)
 ========================================
 Total (Kernel + User Mode) 65536
 -------------------------- -------------
 User Mode                  36864
 -------------------------- -------------
 Peak User Mode             36864
 -------------------------- -------------

스크립트를 종료하려면 명령 프롬프트 창에 Ctrl+C를 입력한 다음 Y에 "일괄 처리 작업 종료?" 프롬프트에 응답합니다.

Windows PowerShell

while ($true) {
    az sphere device app show-memory-stats
    Start-Sleep -Seconds 1
}

메모리 사용량 및 디버거

디버거에서 앱을 실행할 때 보고된 메모리 통계에는 디버깅 서버 프로세스의 메모리 사용량 및 디버깅으로 인한 기타 추가 메모리 사용량(예: 중단점 설정)도 포함됩니다. 따라서 정확한 메모리 통계를 수집하려고 할 때 디버깅하지 않고 항상 앱을 실행해야 합니다.

그러나 디버거를 사용하여 앱을 실행하는 경우 메모리 사용량 프로파일러를 사용하는 것이 유용할 수 있습니다. 메모리 사용량의 상대적 변화를 관찰하면서 중단점을 설정하고 코드 줄을 단계별로 실행하는 것은 메모리 사용량 급증 또는 메모리 누수의 원인을 식별하는 데 유용한 기술일 수 있습니다.

Visual Studio에서 디버깅할 때 성능 프로파일러가 자동으로 열리지만 힙 메모리 할당 추적은 표시되지 않습니다.