Dela via


Metodtips för hantering av RAM-användning i program på hög nivå

Även om Azure Sphere-operativsystemet använder Linux-kärnan som bas är det viktigt att komma ihåg att du fortfarande skriver program för en inbäddad enhet med betydande RAM-begränsningar. Genom att använda bra inbäddade programmeringsmetoder kan du skapa tillförlitliga Azure Sphere-program.

Viktigt

För att få korrekt INFORMATION om RAM-användning för ditt program är det viktigt att du kör appen utan att felsöka. Om du kör appen under felsökaren får du uppblåst RAM-användning eftersom RAM-minne som används av felsökningsservern inkluderas i den rapporterade RAM-användningsstatistiken. Mer information om minnesstatistik för program som körs på den anslutna enheten finns i Minnesanvändning i program på hög nivå.

Här är några metodtips att följa:

  • Allokera minnet i förväg (helst statiskt) och lämna det allokerat för programmets livslängd när det är möjligt. Detta kommer att kraftigt öka determinism av programmets RAM-användning, och minska risken för minnesavtryck ökar och fragmentering under programmets livstid.
  • När dynamisk allokering är absolut nödvändigt:
    • Försök att minimera frekvensen för heapminnesallokeringar och deallocations som utförs av programmet för att minska riskerna för minnesfragmentering av heap, till exempel genom att utnyttja tekniker för segmentallokering/minnespool.
    • Granska stacksidor och om möjligt slå in samtal till malloc() med samtal för att memset() tvinga sidor att genomföra. Detta säkerställer att om en allokering gör att programmet överskrider RAM-gränsen avslutas operativsystemet omedelbart och förutsägbart. Att vänta på att få åtkomst till tilldelade sidor innebär en risk för en fördröjd minneskrasch, vilket är svårare att reproducera och diagnostisera.
    • Aktivera minnesallokeringsspårning för heap när du är i utvecklingsläge.
  • Undvik att använda Log_Debug med stora strängar och ta bort dessa anrop (till exempel med ett #ifdef) när de inte är i utvecklingsläge. Log_Debug orsakar att tillfälliga buffertar tilldelas, vilket leder till plötsliga sekvenser i RAM-användning när de används med stora strängar.
  • Använd EventLoop-API :t när det är möjligt för periodiska asynkrona uppgifter (t.ex. interagera med kringutrustning) i stället för att skapa trådar. Att skapa trådar gör att Linux-kerneln allokerar ytterligare minne som tillskrivs programmet. Detta minskar determinismen för din app eftersom det ökar sannolikheten för att OS-schemaläggaren växlar mellan flera distinkta åtgärder som kan göra att programmet överskrider RAM-gränsen. Många azure sphere-exempelprogram, till exempel GPIO_HighLevelApp, visar hur du använder EventLoop.
  • Undvik att använda minnescacheminnen i förtid för värden som kan omkomputeras under körning.
  • När du använder libcurl:
    • Justera maxstorleken för socketbufferten när du använder libcurl. Azure Sphere OS allokerar socketbuffertar som tillskrivs programmets RAM-användning. Att minska dessa buffertstorlekar kan vara ett bra sätt att minska ram-fotavtrycket för programmet. Observera att libcurl kan påverkas negativt om man gör socketbuffertarna för små. Justera i stället de maximala buffertstorlekarna för ditt scenario:

          static int sockopt_callback(void* clientp, curl_socket_t curlfd, curlsocktype purpose)
          {
              int size = /*specify max buffer sizes here (in bytes)*/
              int size_size = sizeof(size);
              setsockopt(curlfd, SOL_SOCKET, SO_SNDBUF, &size, &size_size);
              setsockopt(curlfd, SOL_SOCKET, SO_RCVBUF, &size, &size_size);
              return CURL_SOCKOPT_OK;
          }
      
          // Place the following along with other calls to curl_easy_setopt
          curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, &sockopt_callback);
      

      Se dokumentationen för CURLOPT_SOCKOPTFUNCTION libcurl.

      • Parametrarna för CURLOPT_BUFFERSIZE och CURLOPT_UPLOAD_BUFFERSIZE på högre nivå kan finjusteras på samma sätt.

      • Libcurl stöder också åsidosättande av interna minnesfunktioner genom att använda curl_global_init_mem och skicka in återanropsfunktioner för malloc, free, realloc, strdupoch calloc. Med den här funktionen kan du hålla reda på dynamiska allokeringar eller till och med ändra beteende. Du kan till exempel allokera en minnespool i förväg och sedan använda dessa återanrop för att allokera libcurl-minne från den poolen. Detta kan vara en effektiv teknik för att ställa in skyddsräcken och öka determinism av din ansökan. Mer information om hur du använder dessa återuppringningar finns i dokumentationen till curl_global_init_mem libcurl.

        Observera

        Denna återanropsmekanism täcker inte alla minnestilldelningar som orsakas av libcurl, bara de som görs direkt av själva libcurl. Närmare bestämt spåras inte allokeringar som görs av wolfSSL under.