Wykorzystanie pamięci w aplikacjach wysokiego poziomu

Ten temat zawiera szczegółowe informacje na temat używania pamięci w aplikacjach wysokiego poziomu. Zobacz Zarządzanie zagadnieniami dotyczącymi pamięci i opóźnień , aby uzyskać informacje o pamięci dostępnej w aplikacjach obsługujnych w czasie rzeczywistym (RTApps).

Aplikacje wysokiego poziomu mają dostęp do następującej pamięci i pamięci:

  • 256 pamięci RAM KiB na rdzeniu wysokiego poziomu, zarezerwowana wyłącznie do użytku w aplikacjach wysokiego poziomu. Do 1 KiB tego miejsca może zostać przydzielonych do każdego udostępnionego kanału buforowego, za pośrednictwem którego komunikują się aplikacje wysokiego poziomu i aplikacje RTApps.
  • 1 Pamięć flash tylko do odczytu MiB, która jest współużytkowana między rdzeniami wysokiego poziomu i w czasie rzeczywistym.
  • Pamięć do odczytu i zapisu (z możliwością wyciszenia), która utrzymuje się po ponownym uruchomieniu urządzenia. Aby uzyskać informacje na temat magazynu z możliwością wyciszenia, zobacz Korzystanie z magazynu w usłudze Azure Sphere.

Uwaga

Wielokrotne aktualizowanie lampy błyskowej w końcu go zużywa i sprawia, że jest nieprawidłowy. Dlatego należy zaprojektować kod, aby uniknąć niepotrzebnych aktualizacji lampy błyskowej. Jeśli na przykład chcesz zapisać stan aplikacji przed zamknięciem, aby można było odzyskać zapisany stan po ponownym uruchomieniu, rozważ zapisanie stanu aplikacji w trybie flash tylko wtedy, gdy stan uległ zmianie.

Określanie użycia pamięci flash

Aby określić użycie pamięci flash, należy wziąć pod uwagę tylko rozmiar pliku pakietu obrazów, który zawiera metadane obrazu, manifest aplikacji i obraz wykonywalny. Nie musisz uwzględniać przestrzeni dyskowej wymaganej przez składniki dostarczane przez firmę Microsoft, takie jak system operacyjny Azure Sphere lub usługi w czasie wykonywania i biblioteki udostępnione, które sterują urządzeniami peryferyjnymi i umożliwiają połączenie z Azure IoT Hub. Podobnie nie trzeba uwzględniać rozmiaru pełnej kopii zapasowej aplikacji ani składników, które umożliwiają przechodzenie do trybu failover lub wycofywanie w przypadku uszkodzenia lub problemów z aktualizacjami przesyłanych bezprzewodowo.

Jednak podczas tworzenia i debugowania rozmiar debugera jest liczony w stosunku do limitu. Debuger jest automatycznie dodawany przez urządzenie az sphere enable-development i usuwany przez [urządzenie az sphere enable-cloud-test](.. /reference/az sphere-device.md). Rozmiar debugera używanego przez SDK można znaleźć, wyszukując plik gdbserver.imagepackage w folderze DebugTools katalogu instalacji narzędzia Microsoft Azure Sphere SDK.

Polecenie az sphere device sideload zwraca błąd, jeśli pakiet obrazów aplikacji i debuger (jeśli są dostępne) przekraczają łączny limit 1 MiB. Polecenie az sphere image add --image , które przekazuje nowy obraz do wykazu usługi Azure Sphere, również zwraca błąd, jeśli pakiet obrazów przekracza 1 MiB.

Limit 256 pamięci RAM KiB dotyczy samej aplikacji; nie musisz zezwalać na pamięć RAM używaną przez debuger. Dodatkowa pamięć jest zarezerwowana dla alokacji jądra.

Dostępne lampy błyskowe i pamięć RAM mogą wzrosnąć (ale nigdy się nie zmniejszą) w przypadku aplikacji napisanych dla bieżącego mikroukładu Azure Sphere (MT3620). Przyszłe mikroukłady Azure Sphere mogą mieć różne limity.

Poza pamięcią

Jeśli aplikacja używa zbyt dużej ilości pamięci RAM, system operacyjny Azure Sphere kończy ją sygnałem SIGKILL. Na przykład w debugerze zobaczysz następujące informacje:

Child terminated with signal = 0x9 (SIGKILL)

Sygnał SIGKILL występuje również w przypadku, gdy aplikacja wysokiego poziomu nie zakończy się po otrzymaniu żądania SIGTERM. Aby uzyskać szczegółowe informacje , zobacz Cykl życia aplikacji .

Aby uniknąć awarii aplikacji z powodu braku pamięci, zobacz najważniejsze wskazówki dotyczące zarządzania użyciem pamięci RAM w aplikacjach wysokiego poziomu.

Określanie użycia pamięci RAM aplikacji w czasie wykonywania

Usługa Azure Sphere udostępnia kilka funkcji do uzyskiwania informacji o użyciu pamięci w czasie wykonywania. Za ich pomocą można monitorować użycie pamięci w aplikacji wysokiego poziomu, co pozwala na bezpieczne ponowne uruchamianie aplikacji, jeśli użycie pamięci przekracza próg określony w limicie 256 kib. Dostępne funkcje to:

  • Applications_GetTotalMemoryUsageInKB: Uzyskaj łączne zużycie pamięci w kibibytes. Jest to całkowite użycie pamięci fizycznej aplikacji w systemie, w tym alokacje jądra (takie jak bufory dla gniazd) w imieniu aplikacji lub serwera debugowania, zwracane jako wartość pierwotna (w kib).
  • Applications_GetUserModeMemoryUsageInKB: Uzyskaj użycie pamięci w trybie użytkownika w kibibytes. Jest to ilość pamięci fizycznej używanej bezpośrednio przez aplikację, pamięć używana przez dowolne biblioteki w jej imieniu (nazywane również alokacjami anonu ) oraz pamięć używana przez serwer debugowania, zwracana jako wartość surowa (w kib).
  • Applications_GetPeakUserModeMemoryUsageInKB: Uzyskaj szczytowe zużycie pamięci w trybie użytkownika w kibibytes. Jest to maksymalna ilość pamięci użytkownika używana w bieżącej sesji. Podczas testowania użycia pamięci aplikacji należy upewnić się, że ta wartość nigdy nie przekracza 256 KiB. Ta wartość jest resetowana po każdym ponownym uruchomieniu lub ponownym uruchomieniu aplikacji. Użyj tej funkcji, aby uzyskać przybliżone spojrzenie na to, jak blisko aplikacja zbliża się do zalecanego limitu 256 KiB.

Aby używać tych funkcji w aplikacji wysokiego poziomu, dołącz plik nagłówka applications.h. Tych funkcji można używać podczas opracowywania, aby zorientować się w ogólnym użyciu pamięci aplikacji, ale można ich także używać razem z rejestrowaniem w celu przechwytywania informacji z urządzeń w tym polu. Wycinek wykrywania i oczyszczania pamięci pokazuje, jak wykryć nieoczekiwane użycie pamięci i z wdziękiem poradzić sobie z tym problemem.

Uwaga

Te funkcje zwracają zużycie pamięci, jak widać w systemie operacyjnym. Obecnie zwolnienie pamięci przez aplikację do alokacji na hałdzie użytkownika nie jest zgłaszane przez te funkcje. Pamięć zostanie zwrócona do biblioteki malloc do użytku w przyszłości, ale statystyki zgłaszane przez system operacyjny pozostają niezmienione, chyba że pamięć została przydzielona i zwolniona przez sam system operacyjny. Przykładem może być przydzielenie pamięci dla gniazda. W związku z tym te funkcje są przydatne do zrozumienia najgorszych scenariuszy ułatwiających działanie aplikacji w celu zapewnienia maksymalnej niezawodności. Wartości są przybliżone i mogą się różnić w zależności od wersji systemu operacyjnego.

Dodawanie śledzenia alokacji pamięci stosu

Dodatkowe informacje o użyciu pamięci można uzyskać, dodając śledzenie alokacji pamięci stosu, które pokazuje, jakie alokacje użytkowników i jądra są dokonywane przez biblioteki statyczne i połączone dynamicznie. Zapewnia to pełniejszy obraz tego, gdzie pamięć jest używana przez aplikację, aby pomóc Ci używać jej najefektniej. Ta funkcja, dostępna w systemie operacyjnym Azure Sphere w wersji 21.07 lub nowszej oraz w wersji środowiska wykonawczego aplikacji (ARV) 10 lub nowszej, działa tylko na urządzeniu z obsługą deweloperów i tylko wtedy, gdy aplikacja nie jest uruchomiona pod debugerem.

Uwaga

Aby śledzenie alokacji pamięci sterty działało poprawnie, należy wykonać oba zadania konfiguracyjne opisane w tej sekcji. Jeśli tego nie zrobisz, ostrzeżenie zostanie zgłoszone podczas kompilacji, a informacje o pamięci stosu nie zostaną wyświetlone.

Aby włączyć śledzenie alokacji pamięci stosu, musisz wykonać dwie czynności:

  • Dodaj funkcję HeapMemStats do pliku app-manifest.json aplikacji:

      "Capabilities": {
        "HeapMemStats": true
      },
    
  • Dodaj bibliotekę libmalloc do pakietu obrazów, dodając DEBUG_LIB "libmalloc" do azsphere_target_add_image polecenia w pliku CMakeLists.txt aplikacji:

    azsphere_target_add_image_package(${PROJECT_NAME} DEBUG_LIB "libmalloc")
    

Ważne

Ponieważ śledzenie alokacji pamięci sterty działa tylko na urządzeniach z obsługą projektowania, należy wykonać następujące czynności, aby usunąć je z aplikacji przed utworzeniem pakietów obrazów do wdrożenia:

  • Usuń wiersz "HeapMemStats": true" z pliku app-manifest.json aplikacji.
  • Usuń DEBUG_LIB "libmalloc" z azsphere_target_add_image_package(${PROJECT_NAME} DEBUG_LIB "libmalloc" polecenia w pliku CMakeLists.txt aplikacji.

Korzystanie z profilera wydajności programu Visual Studio

Jeśli korzystasz z programu Visual Studio, możesz użyć jego funkcji profilera wydajności, aby uzyskać informacje na temat użycia pamięci aplikacji. Aby zapoznać się z samouczkiem, który korzysta z tego profilera, zobacz Samouczki/pamięćUsage.

Wymagania wstępne

Uruchom profiler użycia pamięci

  1. Wybierz pozycję Debugowanie>profilera wydajności lub naciśnij klawisze Alt+F2 , aby otworzyć okno uruchamiania profilera wydajności.

    Okno profilera wydajności programu Visual Studio

  2. W obszarze Analysis Target (Cel analizy) jeśli funkcja Azure Sphere Device Profiler nie jest widoczna, wybierz pozycję Wybierz element docelowy i wybierz pozycję Azure Sphere Device Profiler.

  3. W obszarze Dostępne narzędzia upewnij się, że pole wyboru Użycie pamięci w usłudze Azure Sphere jest zaznaczone, a następnie wybierz pozycję Rozpocznij , aby otworzyć okno profilowania użycia pamięci i uruchomić profiler pamięci.

  4. Jeśli chcesz wdrożyć lub ponownie uruchomić aplikację, wybierz pozycję Debuguj>start bez debugowania lub naciśnij klawisze Ctrl+F5 , aby wdrożyć aplikację na urządzeniu.

    Ważne

    Aby uzyskać dokładne informacje dotyczące użycia pamięci RAM dla aplikacji, należy [uruchomić aplikację bez debugowania](buid-hl-app.md#build-and-deploy-the-application-in-visual-studio-without-debugging). Uruchomienie aplikacji pod debugerem spowoduje nadmierne użycie pamięci RAM, ponieważ pamięć zużywana przez serwer debugowania zostanie uwzględniona w zgłoszonych statystykach użycia pamięci RAM.

Interpretowanie danych profilerów użycia pamięci

W oknie profilowania użycia pamięci jest wyświetlany widok podobny do następującego:

Okno profilera użycia pamięci programu Visual Studio

Na środku widoku wykres Pamięć fizyczna urządzenia Azure Sphere przedstawia trzy różne statystyki użycia pamięci RAM (wyświetlane najbliższemu kibowi) jako trzy różne wiersze, gdy aplikacja jest uruchomiona:

  • Łącznych: Całkowite użycie pamięci fizycznej aplikacji w systemie, w tym alokacje jądra (takie jak bufory dla gniazd) w imieniu aplikacji lub serwera debugowania.
  • Użytkownika: Ilość pamięci fizycznej używanej bezpośrednio przez aplikację, pamięć używana przez dowolne biblioteki w jej imieniu (nazywana również alokacjami anonu ) oraz pamięć używana przez serwer debugowania.
  • Szczyt użytkownika: Maksymalna ilość pamięci użytkownika używana w bieżącej sesji. Podczas testowania użycia pamięci aplikacji należy upewnić się, że ta wartość nigdy nie przekracza 256 KiB. Dodatkowa pamięć jest zarezerwowana dla alokacji jądra. Ta wartość jest resetowana po każdym ponownym uruchomieniu lub ponownym uruchomieniu aplikacji.

Na wykresie są również kreślone wystąpienia zdarzenia Nowy szczyt (reprezentowanego przez trójkąt). To zdarzenie występuje za każdym razem, gdy istnieje nowe maksimum dla szczytowego użycia pamięci użytkownika. Zdarzenie jest włączone dla ułatwień dostępu czytnika zawartości ekranu.

Jeśli włączono śledzenie alokacji pamięci stosu i aplikacja nie jest uruchomiona pod debugerem, zostanie wyświetlony dodatkowy wykres przedstawiający statystyki pamięci stosu:

  • Total Heap: całkowita pamięć stosu przydzielona przez aplikację lub w jej imieniu, w tym z bibliotek statycznych i dynamicznych.
  • Stos biblioteki udostępnionej: alokacje z dynamicznie połączonych bibliotek udostępnianych przez system operacyjny Azure Sphere.

Użycie pamięci sterty w programie Visual Studio

Powyżej wykresów widok osi czasu wyświetla czas wykonywania aplikacji, skorelowany z danymi na poniższym wykresie. Użyj powiększenia i pomniejszenia , aby skupić się na określonych okresach czasu.

Pod wykresami w widoku tabeli są wyświetlane te same statystyki i zdarzenia pamięci.

Wskazówka

Aby skopiować dane z tabeli do schowka, naciśnij klawisze Ctrl+A w celu zaznaczenia wszystkich wierszy, a następnie naciśnij klawisze Ctrl+C.

Pierwsze dwa wykresy przedstawione w tej sekcji zostały wykonane podczas uruchamiania etapu 1 samouczka Użycie pamięci, który zawiera przeciek pamięci. Użycie pamięci wspina się monotonicznie na każdym wykresie, zapewniając wizualne dowody na wyciek. Gdy przeciek zostanie naprawiony, jak w etapie 2 samouczka Użycie pamięci, wykres rośnie i spada wraz z przydzielaniem i przenoszeniem pamięci.

Użycie pamięci sterty programu Visual Studio bez przecieku pamięci

Wyświetlanie statystyk dotyczących całkowitego użycia pamięci

Polecenie az sphere device app show-memory-stats zwraca statystyki użycia pamięci dotyczące całkowitego użycia pamięci, użycia trybu użytkownika i szczytowego użycia trybu użytkownika w aplikacjach działających na podłączonym urządzeniu. Aby można było uruchomić to polecenie, urządzenie musi mieć skonfigurowaną funkcję appDevelopment device.

Statystyki użycia pamięci RAM wyświetlane podczas działania aplikacji są następujące:

  • Total (Kernel + User Mode): Całkowite użycie pamięci fizycznej aplikacji w systemie, w tym alokacje jądra (takie jak bufory dla gniazd) w imieniu aplikacji lub serwera debugowania.
  • Tryb użytkownika: ilość pamięci fizycznej używanej bezpośrednio przez aplikację, pamięć używana przez dowolne biblioteki w jej imieniu (nazywane również alokacjami anon ) oraz pamięć używana przez serwer debugowania.
  • Szczytowy tryb użytkownika: maksymalna ilość pamięci użytkownika używana w bieżącej sesji. Podczas testowania użycia pamięci aplikacji należy upewnić się, że ta wartość nigdy nie przekracza 256 KiB. Dodatkowa pamięć jest zarezerwowana dla alokacji jądra. Ta wartość jest resetowana po każdym ponownym uruchomieniu lub ponownym uruchomieniu aplikacji.

Jeśli włączono śledzenie alokacji pamięci stosu i aplikacja nie jest uruchomiona pod debugerem, zostaną wyświetlone dodatkowe linie statystyk pamięci stosu:

  • Sterta: Aplikacja + biblioteki statyczne: jądro i alokacje użytkowników z kodu i wszelkich bibliotek połączonych statycznie z nim.
  • Hałda: <dynamiczne alokacje> bibliotek: Alokacje z poszczególnych dynamicznie połączonych bibliotek udostępnianych przez system operacyjny Azure Sphere.

Ciągłe monitorowanie zużycia pamięci

Aby monitorować zużycie pamięci w czasie, możesz użyć skryptów, aby uruchomić aplikację [azsphere device app show-memory-stats](.. Polecenie /reference/az sphere-device.md) w pętli, jak opisano w następujących przykładach:

Wiersz polecenia systemu Windows

Za pomocą Notatnika lub innego edytora tekstów utwórz plik skryptu wsadowego memuse.bat z następującą zawartością:

@echo off

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

Uruchom skrypt partii, wpisując jego nazwę w wierszu polecenia (lub pełną ścieżkę do pliku, jeśli nie znajduje się w bieżącym katalogu):

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
 -------------------------- -------------

Aby zamknąć skrypt, wpisz ctrl+C w oknie wiersza polecenia , a następnie odpowiedz Y na monit "Zakończ zadanie wsadowe?".

Windows PowerShell

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

Użycie pamięci i debuger

Podczas uruchamiania aplikacji w ramach debugera, raportowane statystyki pamięci obejmują również użycie pamięci procesu debugowania serwera i inne dodatkowe użycie pamięci spowodowane przez debugowanie, takie jak ustawianie punktów przerwania. Z tego powodu zawsze należy uruchomić aplikację bez debugowania podczas próby zbierania dokładnych statystyk pamięci.

Jednak użycie profilera użycia pamięci może być przydatne, jeśli uruchomisz aplikację z debugerem. Ustawianie punktów przerwania i przechodzenie przez wiersze kodu podczas obserwowania względnych zmian zużycia pamięci może być przydatną techniką identyfikowania przyczyn skoków użycia pamięci lub przecieków pamięci.

Podczas debugowania w programie Visual Studio profiler wydajności jest otwierany automatycznie, ale nie wyświetla śledzenia alokacji pamięci stosu.