2012-08-30 19 views
7

Possiedo un programma che accetta i dati da un socket, esegue alcuni controlli di qualità e altri condizionali, quindi li scrive in una named pipe. Ho eseguito su valgrind e risolto tutte le perdite di memoria che esistevano in origine. Ho quindi creato un ambiente "demo" su un sistema in cui avevo 32 istanze di questo programma in esecuzione, ognuna delle quali veniva alimentata con dati univoci e ciascuno trasmetteva alla propria pipe. L'abbiamo testato e tutto sembrava andare bene. Poi ho provato a provare lo stress aumentando la velocità con cui i dati vengono inviati ad una velocità assurda e le cose sembravano buone all'inizio ... ma i miei programmi continuavano a consumare sempre più memoria fino a quando non avessi più risorse.come cercare la perdita di memoria valgrind dice che non esiste?

Mi sono rivolto a valgrind e ho eseguito la stessa impostazione, tranne che per ogni programma eseguito in valgrind usando leak-check = full. Sono successe alcune strane cose. In primo luogo, la memoria ha perso, ma solo fino al punto in cui ogni programma ha consumato lo 0,9% della mia memoria (in precedenza il più grande maiale della memoria aveva il 6% della mia memoria). Con valgrind in esecuzione, il costo della CPU dei programmi è aumentato e ora ero al 100% CPU con una media di carico enorme, quindi è possibile che la mancanza di CPU disponibile abbia causato il rallentamento dei programmi tanto che la perdita ha richiesto troppo tempo per manifestare . Quando ho provato a fermare questi programmi, valgrind non mostrava alcuna perdita di memoria diretta, mostrava alcune potenziali perdite di memoria ma li ho controllati e non penso che nessuno di essi rappresenti una vera perdita di memoria; e inoltre la possibile perdita di memoria si è manifestata solo in alcuni kilobyte mentre il programma stava consumando più di 100 MB. Anche la memoria raggiungibile (non trasmessa) riportata da valgrind era nell'intervallo KB, quindi valgrind sembra credere che i miei programmi stiano consumando una frazione della memoria che Top dice che stanno usando.

Ho eseguito alcuni altri test e ottenuto risultati strani. Un singolo programma, anche a tripla velocità in cui è stata rilevata la perdita di memoria originale, non sembra mai consumare più del .9% di memoria, due programmi perdono rispettivamente fino all'1,9 e all'1,3% di memoria, ma non più ecc., È come se il la quantità di memoria trapelata e la frequenza con cui perde è in qualche modo dipendente dal numero di istanze del mio programma in esecuzione in una volta; il che non ha senso, ogni istanza dovrebbe essere indipendente al 100% dagli altri.

Ho anche trovato se eseguo 32 istanze con una sola istanza in esecuzione in valgrind l'istanza valgrinded (che è una parola se dico che è!) Perde memoria, ma ad una velocità inferiore rispetto a quelle che girano al di fuori di valgrind. L'istanza di valgrind dirà ancora che non ho perdite dirette e riporta un consumo di memoria molto inferiore a quello mostrato in Top.

Sono piuttosto perplesso su cosa potrebbe causare questo risultato e perché valgrind si rifiuta di essere a conoscenza della perdita di memoria. Pensavo che potesse essere una libreria esterna, ma in realtà non uso alcuna libreria esterna; solo funzioni/oggetti C++ di base. Ho anche considerato che potrebbero essere i dati scritti sulla pipe di uscita a fare in modo che il buffer cresca indefinitamente, ma 1) dovrebbe esserci un limite superiore che un tale buffer può crescere e 2) una volta che la memoria è trapelata se faccio cadere i dati input rate to nothing la memoria rimane consumata piuttosto che lentamente ridiscende a un valore ragionevole.

Qualcuno può darmi un suggerimento su dove dovrei guardare da qui? Sono totalmente perplesso sul motivo per cui la memoria si sta comportando in questo modo.

Grazie.

+2

Sei sicuro che sia una perdita, e non solo una parte della tua programmazione che raccoglie memoria? hai provato il massiccio? – PlasmaHH

+0

Anch'io ho riscontrato problemi simili (anche se non così bizzarro) e sono molto interessato ai feedback che ottieni. Un suggerimento: potresti chiarire il sistema operativo/versione che stai utilizzando? Presumo che sia un dist di Linux. –

+0

Valgrind esegue il programma in una sandbox e esegue un'enorme quantità di elaborazione. Dovresti aspettarti che abbia un utilizzo della CPU molto più elevato e prestazioni molto più lente rispetto alla stessa applicazione che sta funzionando con valgrind. Vorrei prendere in considerazione se durante lo stress test il programma crei buffer aggiuntivi per contenere dati che non potrebbero arrivare alla pipe e che stanno crescendo (non trapelati, solo crescendo perché non si può mantenere il passo). –

risposta

1

Questo sembra un problema che ho avuto di recente.

Se il programma accetta i dati e li memorizza internamente senza alcun limite, potrebbe essere la lettura e il buffering più veloce di quanto possa emettere i dati. In tal caso, l'utilizzo della memoria continuerà ad aumentare senza limiti.

Più istanze del programma esegui, più lentamente ogni istanza andrà, e più velocemente aumenteranno i buffer.

Questo potrebbe non essere il tuo problema, ma senza ulteriori informazioni è il meglio che posso fare.

+0

Questo era il più vicino al preciso. Supponevo di trasmettere i dati una volta ogni x secondi (confuso da un file di configurazione). Ma a causa di un bug il contatore che memorizzava il mio timeout si stava incrementando all'avvio in modo errato, quindi stavo memorizzando un minuto + di dati. Una tensione eccessiva sul sistema ha causato l'insorgenza del bug che ha incrementato il mio contatore di timeout all'avvio più spesso. Vorrei ringraziare Plasma per aver menzionato il massiccio che mi ha indirizzato nella giusta direzione. Pensavo che memcheck mi dicesse che non c'era molta memoria usata, quindi non guardavo l'uso della memoria interna; Evidentemente ho letto male il memcheck. – dsollen

2

Si dovrebbe prima cercare perdite morbide. Succede quando alcuni statici o singleton aumentano gradualmente alcuni buffer o container e raccolgono rifiuti in esso. Tecnicamente non è una perdita, ma i suoi effetti sono altrettanto negativi.

1

Posso suggerire di provare con MemoryScape? Questo strumento fa un buon lavoro nel rilevamento delle perdite di memoria. Non è gratuito ma, visto il tempo e le energie spese, vale la pena provarlo.