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 attmemset()
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örmalloc
,free
,realloc
,strdup
ochcalloc
. 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.