Domanda

Ho appena iniziato a sperimentare SDL in C ++ e ho pensato che controllare regolarmente la presenza di perdite di memoria potesse essere una buona abitudine da prendere presto.

Con questo in mente, ho eseguito i miei programmi "Hello world" attraverso Valgrind per rilevare eventuali perdite, e sebbene abbia rimosso tutto tranne i SDL_Init () e SDL_Quit () , Valgrind riporta ancora 120 byte persi e 77k ancora raggiungibili.

La mia domanda è: esiste un limite accettabile per le perdite di memoria o devo cercare di rendere completamente privo di perdite tutto il mio codice?

È stato utile?

Soluzione

Fai attenzione che Valgrind non sta rilevando falsi positivi nelle sue misurazioni.

Molte implementazioni ingenue di analizzatori di memoria segnalano la perdita di memoria come una perdita quando non lo è davvero.

Forse potresti leggere alcuni articoli nella sezione dei link esterni dell ' articolo di Wikipedia su Purify . So che la documentazione fornita con Purify descrive diversi scenari in cui si ottengono falsi positivi quando si tenta di rilevare perdite di memoria e quindi continua a descrivere le tecniche utilizzate da Purify per aggirare i problemi.

A proposito, non sono affiliato con IBM in alcun modo. Ho appena usato Purify ampiamente e garantirò la sua efficacia.

Modifica: ecco un eccellente articolo introduttivo che copre la memoria monitoraggio. È specifico di Purify ma la discussione sui tipi di errori di memoria è molto interessante.

HTH.

applausi,

Rob

Altri suggerimenti

Devi stare attento con la definizione di "perdita di memoria". Qualcosa che viene assegnato una volta al primo utilizzo e liberato all'uscita dal programma, a volte viene mostrato da un rilevatore di perdite, perché ha iniziato a contare prima di quel primo utilizzo. Ma non è una perdita (sebbene possa essere una cattiva progettazione, poiché potrebbe essere una sorta di globale).

Per vedere se un determinato blocco di codice perde, è possibile eseguirlo ragionevolmente una volta, quindi cancellare il rilevatore di perdite, quindi eseguirlo di nuovo (questo ovviamente richiede il controllo programmatico del rilevatore di perdite). Cose che "perdono" una volta per esecuzione del programma di solito non importa. Cose che "perdono" ogni volta che vengono eseguiti di solito alla fine contano.

Raramente ho trovato troppo difficile colpire zero su questa metrica, il che equivale a osservare l'uso della memoria strisciante rispetto ai blocchi persi. Avevo una libreria in cui è diventato così complicato, con cache, mobili dell'interfaccia utente e quant'altro, che ho appena eseguito la mia suite di test tre volte, e ho ignorato qualsiasi "perdita". che non si è verificato in multipli di tre blocchi. Ho ancora colto tutte o quasi tutte le vere perdite, e ho analizzato i rapporti difficili una volta che avessi tolto il frutto dalla bassa pendenza. Ovviamente i punti deboli dell'uso della suite di test a questo scopo sono (1) che è possibile utilizzare solo le parti di essa che non richiedono un nuovo processo e (2) la maggior parte delle perdite riscontrate è dovuta al codice di test , non il codice della libreria ...

Vivere con perdite di memoria (e altri problemi trascurati) è, nella migliore delle ipotesi, (secondo me) una pessima programmazione. Nel peggiore dei casi, rende il software inutilizzabile.

Dovresti evitare di introdurli in primo luogo ed eseguire gli strumenti che tu e altri avete citato per cercare di rilevarli.

Evita la programmazione sciatta - ci sono già abbastanza programmatori cattivi là fuori - il mondo non ha bisogno di un altro.

Modifica

Sono d'accordo - molti strumenti possono fornire falsi positivi.

Se sei davvero preoccupato per la perdita di memoria, dovrai fare alcuni calcoli.

È necessario testare l'applicazione per circa un'ora, quindi calcolare la memoria perduta. In questo modo, si ottiene un valore di byte / minuto di memoria trapelata.

Ora dovrai stimare la durata media della sessione del tuo programma. Ad esempio, per notepad.exe, 15 minuti mi sembrano una buona stima.

If ( durata media della sessione) * (byte perduti / minuto) > 0,3 * (spazio di memoria normalmente occupato dal processo) , probabilmente dovresti fare qualche sforzo in più per ridurre le perdite di memoria. Ho appena creato 0,3, uso il buon senso per determinare la soglia accettabile.

Ricorda che un aspetto importante dell'essere programmatore è essere un ingegnere del software, e molto spesso l'ingegneria riguarda la scelta dell'opzione meno peggiore tra due o più opzioni sbagliate. La matematica è sempre utile quando è necessario misurare quanto un'opzione sia effettivamente negativa.

Per un'applicazione desktop, piccole perdite di memoria non sono un vero problema. Per i servizi (server) non sono accettabili perdite di memoria.

La maggior parte dei sistemi operativi (incluso Windows) restituirà tutta la memoria allocata di un programma quando il programma viene scaricato. Ciò include qualsiasi memoria di cui il programma stesso potrebbe aver perso la traccia.

Detto questo, la mia solita teoria è che va benissimo perdere la memoria durante l'avvio, ma non OK per farlo durante il runtime.

Quindi davvero la domanda non è se stai perdendo memoria , è se la perdi continuamente durante il runtime del tuo programma. Se usi il tuo programma per un po ', e non importa quello che fai rimane a 120 byte persi anziché aumentare, direi che hai fatto benissimo. Vai avanti.

Dipende dalla tua applicazione. Alcune perdite potrebbero essere inevitabili (a causa del tempo necessario per trovare le scadenze di perdite rispetto a quelle). Finché la tua applicazione può funzionare quanto vuoi e non occupare una quantità folle di memoria in quel momento probabilmente va bene.

Sembra che gli sviluppatori SDL non usino Valgrind, ma in pratica mi importa solo di quei 120 byte persi.

  

Con questo in mente, ho eseguito i miei programmi "Hello world" attraverso Valgrind per rilevare eventuali perdite e, sebbene abbia rimosso tutto tranne le più elementari istruzioni SDL_Init () e SDL_Quit (), Valgrind riporta ancora 120 byte persi e 77k ancora raggiungibili.

Bene, con Valgrind, "memoria ancora raggiungibile" spesso non è proprio una perdita di memoria, specialmente in un programma così semplice. Posso scommettere tranquillamente che praticamente non c'è allocazione in SDL_Quit (), quindi il "leaks" sono solo strutture allocate una volta da SDL_Init ().

Prova ad aggiungere lavoro utile e vedi se tali importi aumentano; prova a fare un ciclo di lavoro utile (come creare e distruggere una struttura SDL) e vedere se la quantità di perdite aumenta con la quantità di iterazioni. In quest'ultimo caso, è necessario controllare le tracce dello stack delle perdite e correggerle.

Altrimenti, quelle perdite da 77k contano come "memoria che dovrebbe essere liberata alla fine del programma, ma per la quale si affidano al sistema operativo per liberarla.

Quindi, in realtà, in questo momento sono più preoccupato per quei 120 byte, se non sono falsi positivi e di solito sono pochi. I falsi positivi con Valgrind sono per lo più casi in cui è previsto l'uso di memoria non inizializzata (ad esempio perché in realtà è un riempimento).

Secondo i commenti di Rob Wells su Purify, scarica e prova alcuni degli altri strumenti disponibili. Uso BoundsChecker e AQTime e ho visto diversi falsi positivi in ??entrambi negli anni. Si noti che la perdita di memoria potrebbe anche essere in un componente di terze parti, che è possibile escludere dall'analisi. Dall'esempio, MFC presentava una serie di perdite di memoria nelle prime versioni di visualizzazione.

IMO, le perdite di memoria dovrebbero essere rintracciate per qualsiasi codice che sta entrando in una base di codice che potrebbe avere una lunga durata. Se non riesci a rintracciarli, almeno annota che esistono per il prossimo utente dello stesso codice.

Le perdite di memoria firstable sono solo un problema serio quando crescono nel tempo, altrimenti l'app sembra un po 'più grande dall'esterno (ovviamente c'è anche un limite qui, quindi il' serio '). Quando hai una perdita che cresce nel tempo potresti essere nei guai. Quanti problemi dipendono dalle circostanze però. Se sai dove sta andando la memoria e puoi assicurarti di avere sempre abbastanza memoria per eseguire il programma e tutto il resto su quella macchina, stai ancora bene. Se non sai dove sta andando la memoria, non spedirei il programma e continuerei a scavare.

Con SDL su Linux in particolare, sembrano esserci delle perdite nella libreria di X windows sottostante. Non c'è molto che puoi fare al riguardo (a meno che tu non voglia provare a riparare la libreria stessa, il che probabilmente non è adatto ai deboli di cuore).

Puoi usare il meccanismo di soppressione di valgrind (vedi --suppressions e --gen-soppressions nella pagina man di valgrind) per dirgli di non disturbarti con questi errori.

In generale dobbiamo essere un po 'più indulgenti con le librerie di terze parti; mentre non dovremmo assolutamente accettare perdite di memoria nel nostro codice e la presenza di perdite di memoria dovrebbe essere un fattore importante nella scelta tra librerie di terze parti alternative, a volte non c'è altra scelta che ignorarle (anche se può essere una buona idea segnalarle al manutentore della biblioteca).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top