Aanbevolen procedures voor het beheren van RAM-gebruik in toepassingen op hoog niveau
Hoewel het Azure Sphere-besturingssysteem de Linux-kernel als basis gebruikt, is het belangrijk om te onthouden dat u nog steeds toepassingen schrijft voor een ingesloten apparaat met aanzienlijke RAM-beperkingen. Door goede ingesloten programmeerprocedures toe te passen, kunt u betrouwbare Azure Sphere-toepassingen maken.
Belangrijk
Voor nauwkeurige RAM-gebruiksgegevens voor uw toepassing is het belangrijk dat u uw app uitvoert zonder foutopsporing. Als u uw app uitvoert onder het foutopsporingsprogramma, wordt het RAM-gebruik vergroot, omdat RAM-geheugen dat wordt gebruikt door de foutopsporingsserver, wordt opgenomen in de gerapporteerde statistieken over ram-gebruik. Zie Geheugengebruik in toepassingen op hoog niveau voor meer informatie over geheugenstatistieken voor toepassingen die worden uitgevoerd op het gekoppelde apparaat.
Hier volgen enkele aanbevolen procedures:
- Wijs geheugen vooraf toe (idealiter statisch) en laat het waar mogelijk toegewezen voor de levensduur van uw toepassing. Dit verhoogt het determinisme van het RAM-gebruik van uw toepassing aanzienlijk en vermindert het risico op toename van de geheugenvoetafdruk en fragmentatie gedurende de levensduur van uw toepassing.
- Wanneer dynamische toewijzing absoluut noodzakelijk is:
- Probeer de frequentie van heap-geheugentoewijzingen en deallocations die worden uitgevoerd door de toepassing te minimaliseren om het risico van heapgeheugenfragmentatie te verminderen, bijvoorbeeld door gebruik te maken van chunktoewijzing/geheugengroeptechnieken.
- Bekijk stapelpagina's en, indien mogelijk, wrap-oproepen naar
malloc()
met aanroepen ommemset()
pagina's te dwingen door te voeren. Dit helpt ervoor te zorgen dat als een toewijzing ertoe leidt dat uw toepassing de RAM-limiet overschrijdt, het besturingssysteem deze onmiddellijk en voorspelbaar beëindigt. Wachten op toegang tot toegewezen pagina's leidt tot het risico van een vertraagde crash van het geheugen, wat moeilijker te reproduceren en te diagnosticeren is. - Schakel het bijhouden van heap-geheugentoewijzing in terwijl deze zich in de ontwikkelingsmodus bevindt.
- Vermijd het gebruik
Log_Debug
met grote tekenreeksen en verwijder deze aanroepen (bijvoorbeeld met een#ifdef
) als u zich niet in de ontwikkelmodus bevindt.Log_Debug
zorgt ervoor dat tijdelijke buffers worden toegewezen, wat leidt tot plotselinge bursts in ram-gebruik bij gebruik met grote tekenreeksen. - Gebruik waar mogelijk de EventLoop-API voor periodieke asynchrone taken (zoals interactie met randapparatuur) in plaats van threads te maken. Het maken van threads zorgt ervoor dat de Linux-kernel extra geheugen toewijst dat is toegewezen aan uw toepassing. Dit vermindert het determinisme van uw app, omdat het de kans verhoogt dat de besturingssysteemplanner schakelt tussen meerdere, afzonderlijke bewerkingen die ertoe kunnen leiden dat uw toepassing de RAM-limiet overschrijdt. Veel van de Azure Sphere-voorbeeldtoepassingen, zoals de GPIO_HighLevelApp, laten zien hoe u de EventLoop gebruikt.
- Vermijd voortijdig gebruik van geheugencaches voor waarden die tijdens runtime opnieuw kunnen worden gecomputeerd.
- Wanneer u libcurl gebruikt:
Stem de maximale grootte van socketbuffers af bij gebruik van libcurl. Het Azure Sphere-besturingssysteem wijst socketbuffers toe die worden toegeschreven aan het RAM-gebruik van uw toepassing. Het verminderen van deze buffergrootten kan een goede manier zijn om de RAM-footprint van uw toepassing te verminderen. Houd er rekening mee dat het te klein maken van de socketbuffers de prestaties van libcurl nadelig beïnvloedt. Stem in plaats daarvan de maximale buffergrootten voor uw scenario af:
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);
Zie de CURLOPT_SOCKOPTFUNCTION libcurl-documentatie.
De parameters CURLOPT_BUFFERSIZE en CURLOPT_UPLOAD_BUFFERSIZE op een hoger niveau kunnen op dezelfde manier worden afgestemd.
Libcurl ondersteunt ook het overschrijven van de interne geheugenfuncties door callback-functies te gebruiken
curl_global_init_mem
en door te geven voormalloc
,free
,realloc
,strdup
encalloc
. Met deze functionaliteit kunt u dynamische toewijzingen bijhouden of zelfs gedrag wijzigen. U kunt bijvoorbeeld vooraf een groep geheugen toewijzen en vervolgens deze callbacks gebruiken om libcurl-geheugen uit die pool toe te wijzen. Dit kan een effectieve techniek zijn voor het instellen van vangrails en het verhogen van determinisme van uw toepassing. Zie de curl_global_init_mem libcurl-documentatie voor meer informatie over het gebruik van deze callbacks.Opmerking
Dit callback-mechanisme dekt niet alle geheugentoewijzingen die worden veroorzaakt door libcurl, alleen die rechtstreeks door libcurl zelf worden gemaakt. Met name worden toewijzingen die door wolfSSL eronder worden gemaakt, niet bijgehouden.