La frammentazione dell'heap è un problema nel braccio bare-metal con g ++?

3

Sto convertendo un progetto da C a misto C / C ++. Sta andando piuttosto bene, e le nuove funzionalità stanno davvero alleggerendo il lavoro.

La piattaforma è un ARM SAM4, il compilatore è arm-none-eabi-g ++. Questa non è un'apparecchiatura di sicurezza, ma potrebbe essere lasciata in funzione per mesi e non dovrebbe riavviarsi sporadicamente.

Il progetto C originale è riuscito a risolvere abbastanza facilmente problemi senza una sola chiamata malloc , allocando staticamente tutti i dati necessari. Ad esempio, gli array con dimensioni sconosciute sono allocati alla dimensione massima prevista.

Ora sto prendendo in considerazione che posso farcela usando new . Ad esempio, tutti i contenitori STL conservano il loro contenuto nell'heap. L'aggiunta di un nuovo elemento a vector può causare la de-allocazione di un'intera regione dell'heap e l'allocazione di un altro.

Ci saranno problemi di frammentazione?

Related:

Cos'è la frammentazione della memoria?

    
posta Vorac 17.06.2014 - 14:17
fonte

3 risposte

4

Non c'è modo di dire se la frammentazione dell'heap sarà un problema nella tua applicazione . Non possiamo dirlo, perché la frammentazione dell'heap è il risultato di determinati schemi di utilizzo della memoria (de-) allocator e non hai fornito alcuna informazione su quel pattern.

In generale, ci si può aspettare problemi di frammentazione se si assegnano e deallocano costantemente oggetti con dimensioni e durata variabili diverse, così che sarebbe raro essere in grado di adattare una nuova richiesta di memoria in uno slot che è stato recentemente rilasciato o che molti le allocazioni di memoria lascerebbero un piccolo numero inutilizzabile di byte inutilizzati tra di loro. Tali modelli possono essere molto sottili e dipendono anche dalla strategia di allocazione utilizzata da new / delete . Si noti inoltre che gli oggetti trapelati ottengono effettivamente una durata eterna per quanto riguarda la gestione della memoria.

Puoi provare ad evitare la frammentazione impostando più allocatori, in modo da poter allocare diversi tipi di oggetti da diversi pool. Se tutti gli oggetti in un pool sono vicini alla stessa dimensione, la frammentazione non sarà un problema.

Un'altra opzione è cercare di organizzare le allocazioni in modo tale che gli oggetti con una durata simile siano allocati vicini (nel tempo). Ciò limita anche le possibilità di ottenere la frammentazione, perché gli oggetti che sono sempre presenti saranno vicini tra loro in una parte dell'heap e gli oggetti più volatili verranno allocati da una parte diversa dell'heap.

La crescita di una std::vector<> non causa la frammentazione della memoria, ma ha il brutto effetto collaterale di cui hai effettivamente bisogno per raddoppiare la normale quantità di memoria durante la crescita del vettore. Questo può essere un problema se hai solo una quantità limitata di RAM disponibile.
Per evitare questo problema, puoi utilizzare std::vector<>::reserve() per impostare la memoria allocata vicino al massimo previsto.

    
risposta data 17.06.2014 - 15:01
fonte
4

Lavorando in un ambiente con memoria limitata (qualcosa che pochi di noi fanno in questi giorni), è del tutto ragionevole non utilizzare alcuna allocazione dell'heap. E C ++ può funzionare molto bene per renderlo possibile.

Sì, le collezioni C ++ per la maggior parte usano l'heap, perché sono progettate per crescere senza limiti. Sì, è quasi impossibile garantire che l'heap non venga mai frammentato, utilizzando l'allocatore predefinito. Non lo userei senza un sacco di pensiero precedente.

Questo ti offre due scelte generali. O rispetta le raccolte non heap (che significa std :: array), o scrivi il tuo allocatore.

Il wrapping degli array esistenti in std :: array offre alcuni vantaggi, ma dovrai decidere se valga la pena.

Un allocatore personalizzato può sfruttare le tue conoscenze su come e quando recuperare la memoria. Ciò potrebbe essere conservando liste libere, o tramite reset periodico, o usando pool, o qualche altra strategia. Dipende da quanto è prezioso l'heap per te.

Indipendentemente da ciò, il C ++ ha molti altri vantaggi. Forse l'heap è solo un gradino troppo lontano.

    
risposta data 17.06.2014 - 16:11
fonte
0

Se il codice C è scritto in modo tale che non ci siano problemi di frammentazione, è possibile scrivere al 100% un codice simile in C ++.

Potresti usare std::array invece di std::vector .

Aggiungerò che mi sembra che tu stia cercando di risolvere un problema che non c'è.

    
risposta data 17.06.2014 - 15:31
fonte

Leggi altre domande sui tag